@@ -24,6 +24,26 @@ WebrtcVideoRendererD3D11Impl::WebrtcVideoRendererD3D11Impl(HWND wnd)
24
24
CreateDXGIFactory (__uuidof (IDXGIFactory2), (void **)(&dxgi_factory_));
25
25
}
26
26
27
+ // The swapchain needs to use window height/width of even number.
28
+ bool WebrtcVideoRendererD3D11Impl::GetWindowSizeForSwapChain (int & width, int & height) {
29
+ if (!wnd_ || !IsWindow (wnd_))
30
+ return false ;
31
+
32
+ RECT rect;
33
+ GetClientRect (wnd_, &rect);
34
+ width = rect.right - rect.left ;
35
+ height = rect.bottom - rect.top ;
36
+
37
+ if (width % 2 ) {
38
+ window_width += 1 ;
39
+ }
40
+ if (height % 2 ) {
41
+ height += 1 ;
42
+ }
43
+
44
+ return true ;
45
+ }
46
+
27
47
void WebrtcVideoRendererD3D11Impl::OnFrame (
28
48
const webrtc::VideoFrame& video_frame) {
29
49
uint16_t width = video_frame.video_frame_buffer ()->width ();
@@ -36,6 +56,8 @@ void WebrtcVideoRendererD3D11Impl::OnFrame(
36
56
if (!wnd_ || !IsWindow (wnd_) || !IsWindowVisible (wnd_))
37
57
return ;
38
58
59
+ // Window width here is used to scale down the I420 frame,
60
+ // so we're not rounding it up to even number.
39
61
RECT rect;
40
62
GetClientRect (wnd_, &rect);
41
63
int window_width_ = rect.right - rect.left ;
@@ -132,17 +154,12 @@ bool WebrtcVideoRendererD3D11Impl::InitSwapChain(int width,
132
154
}
133
155
134
156
HRESULT hr = S_OK;
135
- RECT rect;
136
- GetClientRect (wnd_, &rect);
137
- window_width = rect.right - rect.left ;
138
- window_height = rect.bottom - rect.top ;
139
157
140
- if (window_width % 2 ) {
141
- window_width += 1 ;
142
- }
143
- if (window_height % 2 ) {
144
- window_height += 1 ;
158
+ if (!GetWindowSizeForSwapChain (window_width, window_height)) {
159
+ RTC_LOG (LS_ERROR) << " Failed to get window size for swapchian." ;
160
+ return false ;
145
161
}
162
+
146
163
rtc::CritScope lock (&d3d11_texture_lock_);
147
164
if (swap_chain_for_hwnd_) {
148
165
DXGI_SWAP_CHAIN_DESC desc;
@@ -161,7 +178,7 @@ bool WebrtcVideoRendererD3D11Impl::InitSwapChain(int width,
161
178
hr = swap_chain_for_hwnd_->ResizeBuffers (0 , window_width, window_height,
162
179
DXGI_FORMAT_UNKNOWN, desc.Flags );
163
180
if (FAILED (hr)) {
164
- RTC_LOG (LS_ERROR) << " failed to resize buffer for swapchain." ;
181
+ RTC_LOG (LS_ERROR) << " Failed to resize buffer for swapchain." ;
165
182
return false ;
166
183
}
167
184
} else {
@@ -234,8 +251,10 @@ void WebrtcVideoRendererD3D11Impl::RenderNativeHandleFrame(
234
251
235
252
ID3D11Device* render_device = native_handle->d3d11_device ;
236
253
237
- if (!render_device)
254
+ if (!render_device) {
255
+ RTC_LOG (LS_ERROR) << " Decoder passed an invalid d3d11 device." ;
238
256
return ;
257
+ }
239
258
240
259
d3d11_device_ = render_device;
241
260
d3d11_texture_ = native_handle->texture ;
@@ -258,29 +277,28 @@ void WebrtcVideoRendererD3D11Impl::RenderNV12DXGIMPO(int width, int height) {
258
277
return ;
259
278
}
260
279
261
- RECT rect;
262
- GetClientRect (wnd_, &rect);
263
- window_width = rect.right - rect.left ;
264
- window_height = rect.bottom - rect.top ;
265
-
266
- if (window_width % 2 ) {
267
- window_width += 1 ;
268
- }
269
- if (window_height % 2 ) {
270
- window_height += 1 ;
280
+ if (!GetWindowSizeForSwapChain (window_width, window_height)) {
281
+ RTC_LOG (LS_ERROR) << " Failed to get window size for swapchain." ;
282
+ return ;
271
283
}
284
+
272
285
if (!d3d11_video_device_) {
273
286
hr = d3d11_device_->QueryInterface (__uuidof (ID3D11VideoDevice),
274
287
(void **)&d3d11_video_device_);
275
- if (FAILED (hr))
288
+ if (FAILED (hr)) {
289
+ RTC_LOG (LS_ERROR)
290
+ << " Failed to get d3d11 video device from d3d11 device." ;
276
291
return ;
292
+ }
277
293
}
278
294
279
295
if (swap_chain_for_hwnd_) {
280
296
DXGI_SWAP_CHAIN_DESC desc;
281
297
hr = swap_chain_for_hwnd_->GetDesc (&desc);
282
- if (FAILED (hr))
298
+ if (FAILED (hr)) {
299
+ RTC_LOG (LS_ERROR) << " Failed to get the swapchain descriptor." ;
283
300
return ;
301
+ }
284
302
285
303
if (desc.BufferDesc .Width != (unsigned int )window_width ||
286
304
desc.BufferDesc .Height != (unsigned int )window_height) {
@@ -290,18 +308,23 @@ void WebrtcVideoRendererD3D11Impl::RenderNV12DXGIMPO(int width, int height) {
290
308
291
309
hr = swap_chain_for_hwnd_->ResizeBuffers (0 , window_width, window_height,
292
310
DXGI_FORMAT_UNKNOWN, desc.Flags );
293
- if (FAILED (hr))
311
+ if (FAILED (hr)) {
312
+ RTC_LOG (LS_ERROR) << " Resizing compositor swapchain failed." ;
294
313
return ;
314
+ }
295
315
}
296
316
}
297
317
318
+ // We are actually not resetting video processor when no input/output size change.
298
319
bool reset = false ;
299
320
300
321
if (!d3d11_video_context_) {
301
322
hr = d3d11_device_context_->QueryInterface (__uuidof (ID3D11VideoContext),
302
323
(void **)&d3d11_video_context_);
303
- if (FAILED (hr))
324
+ if (FAILED (hr)) {
325
+ RTC_LOG (LS_ERROR) << " Querying d3d11 video context failed." ;
304
326
return ;
327
+ }
305
328
}
306
329
307
330
if (!CreateVideoProcessor (width, height, reset))
@@ -369,21 +392,12 @@ bool WebrtcVideoRendererD3D11Impl::InitMPO(int width, int height) {
369
392
RECT rect;
370
393
GetClientRect (wnd_, &rect);
371
394
372
- // width and height has to be even number
373
- int rect_width = rect.right - rect.left ;
374
- int rect_height = rect.bottom - rect.top ;
375
-
376
- window_width = rect_width;
377
- window_height = rect_height;
378
-
379
- if (window_width % 2 ) {
380
- window_width += 1 ;
381
- }
382
- if (window_height % 2 ) {
383
- window_height += 1 ;
395
+ if (!GetWindowSizeForSwapChain (window_width, window_height)) {
396
+ RTC_LOG (LS_ERROR) << " Failed to get window size for creating swapchain." ;
397
+ return false ;
384
398
}
385
- swapChainDesc.Width = (rect_width % 2 != 0 ) ? (rect_width + 1 ) : rect_width ;
386
- swapChainDesc.Height = (rect_height % 2 != 0 ) ? (rect_height + 1 ) : rect_height ;
399
+ swapChainDesc.Width = window_width ;
400
+ swapChainDesc.Height = window_height ;
387
401
swapChainDesc.Format = DXGI_FORMAT_NV12;
388
402
swapChainDesc.Stereo = false ;
389
403
swapChainDesc.SampleDesc .Count = 1 ; // Don't use multi-sampling.
@@ -427,10 +441,9 @@ bool WebrtcVideoRendererD3D11Impl::CreateVideoProcessor(int width,
427
441
if (width < 0 || height < 0 )
428
442
return false ;
429
443
430
- RECT rect;
431
- GetClientRect (wnd_, &rect);
432
- int window_width = rect.right - rect.left ;
433
- int window_height = rect.bottom - rect.top ;
444
+ if (!GetWindowSizeForSwapChain (window_width, window_height))
445
+ return false ;
446
+
434
447
D3D11_VIDEO_PROCESSOR_CONTENT_DESC content_desc;
435
448
ZeroMemory (&content_desc, sizeof (content_desc));
436
449
@@ -480,13 +493,11 @@ void WebrtcVideoRendererD3D11Impl::RenderD3D11Texture(int width, int height) {
480
493
HRESULT hr = S_OK;
481
494
482
495
if (swap_chain_for_hwnd_ == nullptr ) {
483
- RTC_LOG (LS_ERROR) << " Invalid swap chain ." ;
496
+ RTC_LOG (LS_ERROR) << " Invalid swapchain ." ;
484
497
return ;
485
498
}
486
499
487
500
Microsoft::WRL::ComPtr<ID3D11Texture2D> dxgi_back_buffer;
488
- // hr = swap_chain_for_hwnd_->GetBuffer(0, __uuidof(ID3D11Texture2D),
489
- // (void**)&dxgi_back_buffer);
490
501
hr = swap_chain_for_hwnd_->GetBuffer (0 , IID_PPV_ARGS (&dxgi_back_buffer));
491
502
if (FAILED (hr)) {
492
503
std::string message = std::system_category ().message (hr);
0 commit comments