mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
d3d12videosink: Add direct-swapchain property
Because DXGI flip mode swapchain will disallow GDI operation to a HWND once swapchain is configured, videosink has been creating child window of application's window. However, since window creation would take a few milliseconds, it can cause performance issue such as UI freezing. Adding a property so that videosink can attach DXGI swapchain diretly to application's window in order to improve performance. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7013>
This commit is contained in:
parent
dd1d2f5ff7
commit
e5d2dd8e8d
6 changed files with 284 additions and 18 deletions
|
@ -108,6 +108,7 @@ enum
|
|||
PROP_DISPLAY_FORMAT,
|
||||
PROP_ERROR_ON_CLOSED,
|
||||
PROP_EXTERNAL_WINDOW_ONLY,
|
||||
PROP_DIRECT_SWAPCHAIN,
|
||||
};
|
||||
|
||||
#define DEFAULT_ADAPTER -1
|
||||
|
@ -129,6 +130,7 @@ enum
|
|||
#define DEFAULT_DISPLAY_FORMAT DXGI_FORMAT_UNKNOWN
|
||||
#define DEFAULT_ERROR_ON_CLOSED TRUE
|
||||
#define DEFAULT_EXTERNAL_WINDOW_ONLY FALSE
|
||||
#define DEFAULT_DIRECT_SWAPCHAIN FALSE
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -216,6 +218,7 @@ struct GstD3D12VideoSinkPrivate
|
|||
DXGI_FORMAT display_format = DEFAULT_DISPLAY_FORMAT;
|
||||
std::atomic<gboolean> error_on_closed = { DEFAULT_ERROR_ON_CLOSED };
|
||||
gboolean external_only = DEFAULT_EXTERNAL_WINDOW_ONLY;
|
||||
std::atomic<gboolean> direct_swapchain = { DEFAULT_DIRECT_SWAPCHAIN };
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
|
@ -460,6 +463,24 @@ gst_d3d12_video_sink_class_init (GstD3D12VideoSinkClass * klass)
|
|||
DEFAULT_EXTERNAL_WINDOW_ONLY,
|
||||
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||
|
||||
/**
|
||||
* GstD3D12VideoSink:direct-swapchain:
|
||||
*
|
||||
* Attach DXGI swapchain to external window handle directly, instead of
|
||||
* creating child window. Note that once direct swapchain is configured,
|
||||
* GDI will no longer work with the given window handle.
|
||||
*
|
||||
* If enabled, GstVideoOverlay::set_render_rectangle() will be ignored,
|
||||
* and application should handle window positioning.
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
g_object_class_install_property (object_class, PROP_DIRECT_SWAPCHAIN,
|
||||
g_param_spec_boolean ("direct-swapchain", "Direct Swapchain",
|
||||
"Attach DXGI swapchain to external window handle directly",
|
||||
DEFAULT_DIRECT_SWAPCHAIN,
|
||||
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||
|
||||
/**
|
||||
* GstD3D12VideoSink::overlay:
|
||||
* @d3d12videosink: the d3d12videosink element that emitted the signal
|
||||
|
@ -695,6 +716,9 @@ gst_d3d12_video_sink_set_property (GObject * object, guint prop_id,
|
|||
case PROP_EXTERNAL_WINDOW_ONLY:
|
||||
priv->external_only = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_DIRECT_SWAPCHAIN:
|
||||
priv->direct_swapchain = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -776,6 +800,9 @@ gst_d3d12_video_sink_get_property (GObject * object, guint prop_id,
|
|||
case PROP_EXTERNAL_WINDOW_ONLY:
|
||||
g_value_set_boolean (value, priv->external_only);
|
||||
break;
|
||||
case PROP_DIRECT_SWAPCHAIN:
|
||||
g_value_set_boolean (value, priv->direct_swapchain);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1409,7 +1436,7 @@ gst_d3d12_video_sink_open_window (GstD3D12VideoSink * self)
|
|||
priv->warn_closed_window = TRUE;
|
||||
auto ret = gst_d3d12_window_open (priv->window, self->device,
|
||||
GST_VIDEO_SINK_WIDTH (self), GST_VIDEO_SINK_HEIGHT (self),
|
||||
(HWND) window_handle);
|
||||
(HWND) window_handle, priv->direct_swapchain);
|
||||
|
||||
std::lock_guard < std::recursive_mutex > lk (priv->lock);
|
||||
if (ret == GST_FLOW_OK) {
|
||||
|
|
|
@ -246,6 +246,19 @@ SwapChain::~SwapChain()
|
|||
lock_.unlock ();
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_expected_error (HRESULT hr)
|
||||
{
|
||||
switch (hr) {
|
||||
case DXGI_ERROR_INVALID_CALL:
|
||||
case E_ACCESSDENIED:
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
GstFlowReturn
|
||||
SwapChain::setup_swapchain (GstD3D12Window * window, GstD3D12Device * device,
|
||||
HWND hwnd, DXGI_FORMAT format, const GstVideoInfo * in_info,
|
||||
|
@ -278,8 +291,16 @@ SwapChain::setup_swapchain (GstD3D12Window * window, GstD3D12Device * device,
|
|||
ComPtr < IDXGISwapChain1 > swapchain;
|
||||
auto hr = factory->CreateSwapChainForHwnd (cq_handle, hwnd, &desc, nullptr,
|
||||
nullptr, &swapchain);
|
||||
if (!gst_d3d12_result (hr, device))
|
||||
if (FAILED (hr)) {
|
||||
if (is_expected_error (hr)) {
|
||||
GST_WARNING_OBJECT (window,
|
||||
"Expected error 0x%x, maybe window is being closed", (guint) hr);
|
||||
return GST_D3D12_WINDOW_FLOW_CLOSED;
|
||||
}
|
||||
|
||||
gst_d3d12_result (hr, device);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
hr = swapchain.As (&resource_->swapchain);
|
||||
if (!gst_d3d12_result (hr, device))
|
||||
|
@ -370,8 +391,16 @@ SwapChain::resize_buffer (GstD3D12Window * window)
|
|||
resource_->swapchain->GetDesc (&desc);
|
||||
auto hr = resource_->swapchain->ResizeBuffers (BACK_BUFFER_COUNT,
|
||||
0, 0, render_format_, desc.Flags);
|
||||
if (!gst_d3d12_result (hr, device))
|
||||
if (FAILED (hr)) {
|
||||
if (is_expected_error (hr)) {
|
||||
GST_WARNING_OBJECT (window,
|
||||
"Expected error 0x%x, maybe window is being closed", (guint) hr);
|
||||
return GST_D3D12_WINDOW_FLOW_CLOSED;
|
||||
}
|
||||
|
||||
gst_d3d12_result (hr, device);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
for (guint i = 0; i < BACK_BUFFER_COUNT; i++) {
|
||||
ComPtr < ID3D12Resource > backbuf;
|
||||
|
@ -534,10 +563,13 @@ SwapChain::present ()
|
|||
|
||||
switch (hr) {
|
||||
case DXGI_ERROR_DEVICE_REMOVED:
|
||||
case DXGI_ERROR_INVALID_CALL:
|
||||
case E_OUTOFMEMORY:
|
||||
gst_d3d12_result (hr, resource_->device);
|
||||
return GST_FLOW_ERROR;
|
||||
case DXGI_ERROR_INVALID_CALL:
|
||||
case E_ACCESSDENIED:
|
||||
GST_WARNING ("Present failed, hr: 0x%x", (guint) hr);
|
||||
return GST_D3D12_WINDOW_FLOW_CLOSED;
|
||||
default:
|
||||
/* Ignore other return code */
|
||||
break;
|
||||
|
|
|
@ -30,7 +30,7 @@ GST_DEBUG_CATEGORY_EXTERN (gst_d3d12_window_debug);
|
|||
|
||||
#define WM_GST_D3D12_FULLSCREEN (WM_USER + 1)
|
||||
#define WM_GST_D3D12_ATTACH_INTERNAL_WINDOW (WM_USER + 2)
|
||||
#define WM_GST_D3D12_DETACH_INTERNAL_WINDOW (WM_USER + 3)
|
||||
#define WM_GST_D3D12_CREATE_PROXY (WM_USER + 3)
|
||||
#define WM_GST_D3D12_DESTROY_INTERNAL_WINDOW (WM_USER + 4)
|
||||
#define WM_GST_D3D12_UPDATE_RENDER_RECT (WM_USER + 5)
|
||||
#define WM_GST_D3D12_PARENT_SIZE (WM_USER + 6)
|
||||
|
@ -59,7 +59,7 @@ SwapChainProxy::~SwapChainProxy ()
|
|||
GST_DEBUG_OBJECT (window_, "Destroying proxy %" G_GSIZE_FORMAT, id_);
|
||||
|
||||
swapchain_ = nullptr;
|
||||
if (window_thread_ && hwnd_) {
|
||||
if (window_thread_ && hwnd_ && hwnd_ != parent_hwnd_) {
|
||||
if (window_thread_ == g_thread_self ())
|
||||
DestroyWindow (hwnd_);
|
||||
else
|
||||
|
@ -89,6 +89,12 @@ SwapChainProxy::get_id ()
|
|||
return id_;
|
||||
}
|
||||
|
||||
GstD3D12Window *
|
||||
SwapChainProxy::get_window ()
|
||||
{
|
||||
return window_;
|
||||
}
|
||||
|
||||
bool
|
||||
SwapChainProxy::has_parent ()
|
||||
{
|
||||
|
@ -137,7 +143,7 @@ SwapChainProxy::update_render_rect ()
|
|||
bool send_msg = false;
|
||||
{
|
||||
std::lock_guard <std::recursive_mutex> lk (lock_);
|
||||
if (!hwnd_)
|
||||
if (!hwnd_ || hwnd_ == parent_hwnd_)
|
||||
return;
|
||||
|
||||
if (window_thread_ == g_thread_self ())
|
||||
|
@ -267,7 +273,7 @@ SwapChainProxy::handle_mouse_event (UINT msg, WPARAM wparam, LPARAM lparam)
|
|||
auto xpos = GET_X_LPARAM (lparam);
|
||||
auto ypos = GET_Y_LPARAM (lparam);
|
||||
|
||||
if (parent_hwnd_) {
|
||||
if (parent_hwnd_ && parent_hwnd_ != hwnd_) {
|
||||
POINT updated_pos;
|
||||
updated_pos.x = xpos;
|
||||
updated_pos.y = ypos;
|
||||
|
@ -477,13 +483,47 @@ SwapChainProxy::handle_swapchain_created ()
|
|||
swapchain_->disable_alt_enter (hwnd_);
|
||||
}
|
||||
|
||||
void
|
||||
SwapChainProxy::handle_position_changed (INT width, INT height)
|
||||
{
|
||||
{
|
||||
std::lock_guard <std::recursive_mutex> lk (lock_);
|
||||
if (!hwnd_ || !swapchain_)
|
||||
return;
|
||||
|
||||
if (width != width_ || height != height_) {
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto sc = get_swapchain ();
|
||||
if (sc)
|
||||
sc->resize_buffer (window_);
|
||||
}
|
||||
|
||||
void
|
||||
SwapChainProxy::release_swapchin ()
|
||||
{
|
||||
std::lock_guard <std::recursive_mutex> lk (lock_);
|
||||
swapchain_ = nullptr;
|
||||
}
|
||||
|
||||
GstFlowReturn
|
||||
SwapChainProxy::resize_buffer ()
|
||||
SwapChainProxy::resize_buffer (INT width, INT height)
|
||||
{
|
||||
auto sc = get_swapchain ();
|
||||
if (!sc)
|
||||
return GST_FLOW_OK;
|
||||
|
||||
if (width > 0 && height > 0) {
|
||||
std::lock_guard <std::recursive_mutex> lk (lock_);
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
}
|
||||
|
||||
return sc->resize_buffer (window_);
|
||||
}
|
||||
|
||||
|
@ -570,10 +610,69 @@ parent_wnd_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
|||
server->create_child_hwnd_finish ((GstD3D12Window *) lparam, hwnd,
|
||||
(SIZE_T) wparam);
|
||||
return 0;
|
||||
} else if (msg == WM_GST_D3D12_CREATE_PROXY) {
|
||||
server->create_proxy_finish ((GstD3D12Window *) lparam, hwnd,
|
||||
(SIZE_T) wparam);
|
||||
return 0;
|
||||
}
|
||||
|
||||
server->forward_parent_message (hwnd, msg, wparam, lparam);
|
||||
|
||||
auto direct_proxy = server->get_direct_proxy (hwnd);
|
||||
switch (msg) {
|
||||
case WM_SIZE:
|
||||
{
|
||||
auto dproxy = server->get_direct_proxy (hwnd);
|
||||
if (dproxy)
|
||||
dproxy->resize_buffer (LOWORD (lparam), HIWORD (lparam));
|
||||
break;
|
||||
}
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
WINDOWPOS *pos = (WINDOWPOS *) lparam;
|
||||
if ((pos->flags & SWP_HIDEWINDOW) == 0) {
|
||||
INT width = pos->cx;
|
||||
INT height = pos->cy;
|
||||
if ((pos->flags & SWP_NOSIZE) != 0) {
|
||||
RECT rect = { };
|
||||
GetClientRect (hwnd, &rect);
|
||||
width = rect.right - rect.left;
|
||||
height = rect.bottom - rect.top;
|
||||
}
|
||||
auto dproxy = server->get_direct_proxy (hwnd);
|
||||
if (dproxy)
|
||||
dproxy->handle_position_changed (width, height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
{
|
||||
auto dproxy = server->get_direct_proxy (hwnd);
|
||||
if (dproxy)
|
||||
dproxy->handle_key_event (msg, wparam, lparam);
|
||||
break;
|
||||
}
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
{
|
||||
auto proxy = server->get_direct_proxy (hwnd);
|
||||
if (proxy)
|
||||
proxy->handle_mouse_event (msg, wparam, lparam);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (msg == WM_DESTROY) {
|
||||
GST_INFO ("Parent HWND %p is being destroyed", hwnd);
|
||||
server->on_parent_destroy (hwnd);
|
||||
|
@ -699,7 +798,7 @@ internal_wnd_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
|||
{
|
||||
auto proxy = server->get_proxy (window, id);
|
||||
if (proxy)
|
||||
proxy->resize_buffer ();
|
||||
proxy->resize_buffer (0, 0);
|
||||
break;
|
||||
}
|
||||
case WM_SYSKEYDOWN:
|
||||
|
@ -753,7 +852,7 @@ register_window_class ()
|
|||
|
||||
GstFlowReturn
|
||||
HwndServer::create_child_hwnd (GstD3D12Window * window, HWND parent_hwnd,
|
||||
SIZE_T & proxy_id)
|
||||
gboolean direct_swapchain, SIZE_T & proxy_id)
|
||||
{
|
||||
proxy_id = 0;
|
||||
if (!IsWindow (parent_hwnd)) {
|
||||
|
@ -781,6 +880,31 @@ HwndServer::create_child_hwnd (GstD3D12Window * window, HWND parent_hwnd,
|
|||
"subclass proc installed for hwnd %p", parent_hwnd);
|
||||
}
|
||||
|
||||
/* Cannot attach multiple swapchain to a single HWND.
|
||||
* release swapchain if needed */
|
||||
if (direct_swapchain) {
|
||||
for (auto it : state_) {
|
||||
auto state = it.second;
|
||||
if (state) {
|
||||
auto proxy = state->proxy;
|
||||
if (proxy && proxy->get_window_handle () == parent_hwnd) {
|
||||
proxy->release_swapchin ();
|
||||
std::unique_lock<std::mutex> lk (state->create_lock);
|
||||
state->proxy = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto it = direct_proxy_map_.find (parent_hwnd);
|
||||
if (it != direct_proxy_map_.end ()) {
|
||||
auto proxy = it->second.lock ();
|
||||
if (proxy)
|
||||
proxy->release_swapchin ();
|
||||
}
|
||||
|
||||
direct_proxy_map_.erase (parent_hwnd);
|
||||
}
|
||||
|
||||
auto it = state_.find (window);
|
||||
state = it->second;
|
||||
}
|
||||
|
@ -800,7 +924,8 @@ HwndServer::create_child_hwnd (GstD3D12Window * window, HWND parent_hwnd,
|
|||
}
|
||||
|
||||
state->create_state = CreateState::Waiting;
|
||||
if (!PostMessageW (parent_hwnd, WM_GST_D3D12_ATTACH_INTERNAL_WINDOW,
|
||||
if (!PostMessageW (parent_hwnd, direct_swapchain ?
|
||||
WM_GST_D3D12_CREATE_PROXY: WM_GST_D3D12_ATTACH_INTERNAL_WINDOW,
|
||||
(WPARAM) id, (LPARAM) window)) {
|
||||
GST_WARNING_OBJECT (window, "Couldn't post message");
|
||||
state->create_state = CreateState::None;
|
||||
|
@ -912,6 +1037,43 @@ HwndServer::create_child_hwnd_finish (GstD3D12Window * window,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
HwndServer::create_proxy_finish (GstD3D12Window * window,
|
||||
HWND parent_hwnd, SIZE_T proxy_id)
|
||||
{
|
||||
std::shared_ptr<State> state;
|
||||
std::shared_ptr<SwapChainProxy> proxy;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lk (lock_);
|
||||
auto it = state_.find (window);
|
||||
if (it == state_.end ()) {
|
||||
GST_WARNING ("Window is not registered");
|
||||
return;
|
||||
}
|
||||
|
||||
state = it->second;
|
||||
proxy = state->proxy;
|
||||
|
||||
if (!proxy) {
|
||||
GST_INFO ("Proxy was released");
|
||||
return;
|
||||
}
|
||||
|
||||
if (proxy->get_id () != proxy_id) {
|
||||
GST_INFO ("Different proxy id");
|
||||
return;
|
||||
}
|
||||
|
||||
direct_proxy_map_.insert ({parent_hwnd, proxy});
|
||||
|
||||
{
|
||||
std::lock_guard <std::mutex> lk (state->create_lock);
|
||||
proxy->set_window_handles (parent_hwnd, parent_hwnd);
|
||||
state->create_state = CreateState::Opened;
|
||||
state->create_cond.notify_all ();
|
||||
}
|
||||
}
|
||||
|
||||
SIZE_T
|
||||
HwndServer::create_internal_window (GstD3D12Window * window)
|
||||
{
|
||||
|
@ -1006,6 +1168,15 @@ HwndServer::release_proxy (GstD3D12Window * window, SIZE_T proxy_id)
|
|||
state->proxy = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto dit = direct_proxy_map_.begin ();
|
||||
while (dit != direct_proxy_map_.end ()) {
|
||||
auto proxy = dit->second.lock ();
|
||||
if (!proxy || proxy->get_window () == window)
|
||||
dit = direct_proxy_map_.erase (dit);
|
||||
else
|
||||
dit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1061,6 +1232,18 @@ HwndServer::on_parent_destroy (HWND parent_hwnd)
|
|||
{
|
||||
std::lock_guard <std::recursive_mutex> lk (lock_);
|
||||
parent_hwnd_map_.erase (parent_hwnd);
|
||||
direct_proxy_map_.erase (parent_hwnd);
|
||||
for (auto it : state_) {
|
||||
auto state = it.second;
|
||||
if (state) {
|
||||
auto proxy = state->proxy;
|
||||
if (proxy && proxy->get_window_handle () == parent_hwnd) {
|
||||
proxy->release_swapchin ();
|
||||
std::unique_lock<std::mutex> lk (state->create_lock);
|
||||
state->proxy = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1099,4 +1282,16 @@ HwndServer::get_proxy (GstD3D12Window * window, SIZE_T proxy_id)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::shared_ptr<SwapChainProxy>
|
||||
HwndServer::get_direct_proxy (HWND parent_hwnd)
|
||||
{
|
||||
std::lock_guard <std::recursive_mutex> lk (lock_);
|
||||
auto it = direct_proxy_map_.find (parent_hwnd);
|
||||
if (it == direct_proxy_map_.end ())
|
||||
return nullptr;
|
||||
|
||||
return it->second.lock ();
|
||||
}
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
void set_window_handles (HWND parent_hwnd, HWND child_hwnd);
|
||||
HWND get_window_handle ();
|
||||
SIZE_T get_id ();
|
||||
GstD3D12Window *get_window ();
|
||||
bool has_parent ();
|
||||
void on_destroy ();
|
||||
void set_fullscreen_on_alt_enter (bool enable);
|
||||
|
@ -60,10 +61,12 @@ public:
|
|||
void handle_key_event (UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
void handle_mouse_event (UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
void handle_swapchain_created ();
|
||||
void handle_position_changed (INT width, INT height);
|
||||
void release_swapchin ();
|
||||
GstFlowReturn setup_swapchain (GstD3D12Device * device, DXGI_FORMAT format,
|
||||
const GstVideoInfo * in_info, const GstVideoInfo * out_info,
|
||||
GstStructure * conv_config);
|
||||
GstFlowReturn resize_buffer ();
|
||||
GstFlowReturn resize_buffer (INT width, INT height);
|
||||
GstFlowReturn set_buffer (GstBuffer * buffer);
|
||||
GstFlowReturn present ();
|
||||
|
||||
|
@ -78,6 +81,8 @@ private:
|
|||
GThread *window_thread_ = nullptr;
|
||||
FullscreenState fstate_;
|
||||
std::shared_ptr<SwapChain> swapchain_;
|
||||
INT width_ = 0;
|
||||
INT height_ = 0;
|
||||
|
||||
std::recursive_mutex lock_;
|
||||
};
|
||||
|
@ -104,10 +109,12 @@ public:
|
|||
void unlock_stop_window (GstD3D12Window * window);
|
||||
|
||||
GstFlowReturn create_child_hwnd (GstD3D12Window * window,
|
||||
HWND parent_hwnd, SIZE_T & proxy_id);
|
||||
HWND parent_hwnd, gboolean direct_swapchain, SIZE_T & proxy_id);
|
||||
|
||||
void create_child_hwnd_finish (GstD3D12Window * window,
|
||||
HWND parent_hwnd, SIZE_T proxy_id);
|
||||
void create_proxy_finish (GstD3D12Window * window,
|
||||
HWND parent_hwnd, SIZE_T proxy_id);
|
||||
|
||||
SIZE_T create_internal_window (GstD3D12Window * window);
|
||||
|
||||
|
@ -122,6 +129,7 @@ public:
|
|||
|
||||
std::shared_ptr<SwapChainProxy> get_proxy (GstD3D12Window * window,
|
||||
SIZE_T proxy_id);
|
||||
std::shared_ptr<SwapChainProxy> get_direct_proxy (HWND parent_hwnd);
|
||||
|
||||
private:
|
||||
enum CreateState
|
||||
|
@ -147,5 +155,6 @@ private:
|
|||
std::recursive_mutex lock_;
|
||||
std::unordered_map<GstD3D12Window *, std::shared_ptr<State>> state_;
|
||||
std::unordered_map<HWND, std::vector<HWND>> parent_hwnd_map_;
|
||||
std::unordered_map<HWND, std::weak_ptr<SwapChainProxy>> direct_proxy_map_;
|
||||
};
|
||||
|
||||
|
|
|
@ -335,12 +335,13 @@ gst_d3d12_window_resize_buffer (GstD3D12Window * self)
|
|||
if (!proxy)
|
||||
return GST_FLOW_OK;
|
||||
|
||||
return proxy->resize_buffer ();
|
||||
return proxy->resize_buffer (0, 0);
|
||||
}
|
||||
|
||||
GstFlowReturn
|
||||
gst_d3d12_window_open (GstD3D12Window * window, GstD3D12Device * device,
|
||||
guint display_width, guint display_height, HWND parent_hwnd)
|
||||
guint display_width, guint display_height, HWND parent_hwnd,
|
||||
gboolean direct_swapchain)
|
||||
{
|
||||
auto priv = window->priv;
|
||||
auto server = HwndServer::get_instance ();
|
||||
|
@ -363,7 +364,8 @@ gst_d3d12_window_open (GstD3D12Window * window, GstD3D12Device * device,
|
|||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
auto ret = server->create_child_hwnd (window, parent_hwnd, priv->proxy_id);
|
||||
auto ret = server->create_child_hwnd (window, parent_hwnd,
|
||||
direct_swapchain, priv->proxy_id);
|
||||
if (ret == GST_FLOW_OK)
|
||||
priv->proxy = server->get_proxy (window, priv->proxy_id);
|
||||
|
||||
|
|
|
@ -59,7 +59,8 @@ GstFlowReturn gst_d3d12_window_open (GstD3D12Window * window,
|
|||
GstD3D12Device * device,
|
||||
guint display_width,
|
||||
guint display_height,
|
||||
HWND parent_hwnd);
|
||||
HWND parent_hwnd,
|
||||
gboolean direct_swapchain);
|
||||
|
||||
GstFlowReturn gst_d3d12_window_prepare (GstD3D12Window * window,
|
||||
GstD3D12Device * device,
|
||||
|
|
Loading…
Reference in a new issue