Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit d7d67a5

Browse files
committed
Fix local view freeze for conference application
1 parent 92d2faf commit d7d67a5

File tree

1 file changed

+55
-37
lines changed

1 file changed

+55
-37
lines changed

talk/owt/sdk/base/win/videorendererd3d11.cc

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <array>
77
#include <cstdio>
88
#include "rtc_base/logging.h"
9+
#include <system_error>
910
#include "talk/owt/sdk/base/nativehandlebuffer.h"
1011
#include "talk/owt/sdk/base/win/d3dnativeframe.h"
1112
#include "talk/owt/sdk/include/cpp/owt/base/videorendererinterface.h"
@@ -32,6 +33,14 @@ void WebrtcVideoRendererD3D11Impl::OnFrame(
3233
return;
3334
}
3435

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+
3544
if (video_frame.video_frame_buffer()->type() ==
3645
webrtc::VideoFrameBuffer::Type::kNative) {
3746
D3D11ImageHandle* native_handle = reinterpret_cast<D3D11ImageHandle*>(
@@ -67,29 +76,13 @@ void WebrtcVideoRendererD3D11Impl::OnFrame(
6776
RenderNativeHandleFrame(video_frame);
6877
} else { // I420 frame passed.
6978
// 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-
7579
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-
}
8880
rtc::scoped_refptr<webrtc::I420Buffer> scaled_buffer =
8981
I420Buffer::Create(window_width_, window_height_);
9082
auto i420_buffer = video_frame.video_frame_buffer()->ToI420();
9183
scaled_buffer->ScaleFrom(*i420_buffer);
9284
new_frame.set_video_frame_buffer(scaled_buffer);
85+
9386
RenderI420Frame_DX11(new_frame);
9487
}
9588
return;
@@ -141,8 +134,8 @@ bool WebrtcVideoRendererD3D11Impl::InitSwapChain(int width,
141134
HRESULT hr = S_OK;
142135
RECT rect;
143136
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;
146139

147140
rtc::CritScope lock(&d3d11_texture_lock_);
148141
if (swap_chain_for_hwnd_) {
@@ -154,9 +147,11 @@ bool WebrtcVideoRendererD3D11Impl::InitSwapChain(int width,
154147
return false;
155148
}
156149

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,
160155
DXGI_FORMAT_UNKNOWN, desc.Flags);
161156
if (FAILED(hr)) {
162157
RTC_LOG(LS_ERROR) << "failed to resize buffer for swapchain.";
@@ -171,8 +166,8 @@ bool WebrtcVideoRendererD3D11Impl::InitSwapChain(int width,
171166
ZeroMemory(&desc, sizeof(DXGI_SWAP_CHAIN_DESC1));
172167
desc.BufferCount = 2;
173168
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;
176171
desc.Scaling = DXGI_SCALING_STRETCH;
177172
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
178173
desc.SampleDesc.Count = 1;
@@ -184,23 +179,38 @@ bool WebrtcVideoRendererD3D11Impl::InitSwapChain(int width,
184179
CComPtr<IDXGIDevice2> dxgi_device;
185180
hr = d3d11_device_->QueryInterface(__uuidof(IDXGIDevice1),
186181
(void**)&dxgi_device);
187-
if (FAILED(hr))
182+
if (FAILED(hr)) {
183+
RTC_LOG(LS_ERROR) << "Failed to query dxgi device.";
188184
return false;
185+
}
189186

190187
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter = nullptr;
191188
Microsoft::WRL::ComPtr<IDXGIFactory2> factory = nullptr;
192189

193190
hr = dxgi_device->GetAdapter(&adapter);
194-
if (FAILED(hr))
191+
if (FAILED(hr)) {
192+
RTC_LOG(LS_ERROR) << "Failed to get the adatper.";
195193
return false;
194+
}
196195

197196
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.";
199199
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();
200207

201208
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;
203212
return false;
213+
}
204214

205215
return true;
206216
}
@@ -243,8 +253,15 @@ void WebrtcVideoRendererD3D11Impl::RenderNV12DXGIMPO(int width, int height) {
243253

244254
RECT rect;
245255
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+
}
248265

249266
if (swap_chain_for_hwnd_) {
250267
DXGI_SWAP_CHAIN_DESC desc;
@@ -254,6 +271,10 @@ void WebrtcVideoRendererD3D11Impl::RenderNV12DXGIMPO(int width, int height) {
254271

255272
if (desc.BufferDesc.Width != (unsigned int)window_width ||
256273
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+
257278
hr = swap_chain_for_hwnd_->ResizeBuffers(0, window_width, window_height,
258279
DXGI_FORMAT_UNKNOWN, desc.Flags);
259280
if (FAILED(hr))
@@ -262,12 +283,6 @@ void WebrtcVideoRendererD3D11Impl::RenderNV12DXGIMPO(int width, int height) {
262283
}
263284

264285
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-
}
271286

272287
if (!d3d11_video_context_) {
273288
hr = d3d11_device_context_->QueryInterface(__uuidof(ID3D11VideoContext),
@@ -345,6 +360,9 @@ bool WebrtcVideoRendererD3D11Impl::InitMPO(int width, int height) {
345360
int rect_width = rect.right - rect.left;
346361
int rect_height = rect.bottom - rect.top;
347362

363+
window_width = rect_width;
364+
window_height = rect_height;
365+
348366
swapChainDesc.Width = (rect_width%2) ? (rect_width + 1) : rect_width;
349367
swapChainDesc.Height = (rect_height%2) ? (rect_height + 1) : rect_height;
350368
swapChainDesc.Format = DXGI_FORMAT_NV12;
@@ -396,7 +414,7 @@ bool WebrtcVideoRendererD3D11Impl::CreateVideoProcessor(int width,
396414
int window_height = rect.bottom - rect.top;
397415
D3D11_VIDEO_PROCESSOR_CONTENT_DESC content_desc;
398416
ZeroMemory(&content_desc, sizeof(content_desc));
399-
// Check input size to decide if
417+
400418
if (video_processor_.p && video_processor_enum_.p) {
401419
hr = video_processor_enum_->GetVideoProcessorContentDesc(&content_desc);
402420
if (FAILED(hr))

0 commit comments

Comments
 (0)