mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-06 02:32:23 +00:00
d3dvideosink: fix regression setting window handle in pause/play
https://bugzilla.gnome.org/show_bug.cgi?id=656905
This commit is contained in:
parent
aca69cbf63
commit
6f3ea8e67b
1 changed files with 28 additions and 59 deletions
|
@ -63,7 +63,6 @@ struct _GstD3DVideoSinkHookData
|
||||||
static GstD3DVideoSinkShared shared;
|
static GstD3DVideoSinkShared shared;
|
||||||
/* Define a shared lock to synchronize the creation/destruction of the d3d device */
|
/* Define a shared lock to synchronize the creation/destruction of the d3d device */
|
||||||
static GStaticMutex shared_d3d_lock = G_STATIC_MUTEX_INIT;
|
static GStaticMutex shared_d3d_lock = G_STATIC_MUTEX_INIT;
|
||||||
static G_GNUC_UNUSED GStaticMutex shared_d3d_dev_lock = G_STATIC_MUTEX_INIT;
|
|
||||||
static GStaticMutex shared_d3d_hook_lock = G_STATIC_MUTEX_INIT;
|
static GStaticMutex shared_d3d_hook_lock = G_STATIC_MUTEX_INIT;
|
||||||
/* Hold a reference to our dll's HINSTANCE */
|
/* Hold a reference to our dll's HINSTANCE */
|
||||||
static HINSTANCE g_hinstDll = NULL;
|
static HINSTANCE g_hinstDll = NULL;
|
||||||
|
@ -155,12 +154,11 @@ static void gst_d3dvideosink_remove_window_for_renderer (GstD3DVideoSink *
|
||||||
sink);
|
sink);
|
||||||
static gboolean gst_d3dvideosink_initialize_direct3d (GstD3DVideoSink * sink);
|
static gboolean gst_d3dvideosink_initialize_direct3d (GstD3DVideoSink * sink);
|
||||||
static gboolean gst_d3dvideosink_initialize_d3d_device (GstD3DVideoSink * sink);
|
static gboolean gst_d3dvideosink_initialize_d3d_device (GstD3DVideoSink * sink);
|
||||||
static gboolean gst_d3dvideosink_resize_swap_chain (GstD3DVideoSink * sink,
|
|
||||||
gint width, gint height) G_GNUC_UNUSED;
|
|
||||||
static gboolean gst_d3dvideosink_notify_device_init (GstD3DVideoSink * sink);
|
static gboolean gst_d3dvideosink_notify_device_init (GstD3DVideoSink * sink);
|
||||||
static gboolean gst_d3dvideosink_notify_device_lost (GstD3DVideoSink * sink);
|
static gboolean gst_d3dvideosink_notify_device_lost (GstD3DVideoSink * sink);
|
||||||
static gboolean gst_d3dvideosink_notify_device_reset (GstD3DVideoSink * sink);
|
static gboolean gst_d3dvideosink_notify_device_reset (GstD3DVideoSink * sink);
|
||||||
static gboolean gst_d3dvideosink_notify_device_resize (GstD3DVideoSink * sink);
|
static gboolean gst_d3dvideosink_notify_device_reinit (GstD3DVideoSink * sink);
|
||||||
static gboolean gst_d3dvideosink_device_lost (GstD3DVideoSink * sink);
|
static gboolean gst_d3dvideosink_device_lost (GstD3DVideoSink * sink);
|
||||||
static gboolean gst_d3dvideosink_release_d3d_device (GstD3DVideoSink * sink);
|
static gboolean gst_d3dvideosink_release_d3d_device (GstD3DVideoSink * sink);
|
||||||
static gboolean gst_d3dvideosink_release_direct3d (GstD3DVideoSink * sink);
|
static gboolean gst_d3dvideosink_release_direct3d (GstD3DVideoSink * sink);
|
||||||
|
@ -270,8 +268,7 @@ gst_d3dvideosink_base_init (gpointer klass)
|
||||||
{
|
{
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
|
|
||||||
gst_element_class_add_static_pad_template (element_class,
|
gst_element_class_add_static_pad_template (element_class, &sink_template);
|
||||||
&sink_template);
|
|
||||||
|
|
||||||
gst_element_class_set_details_simple (element_class, "Direct3D video sink",
|
gst_element_class_set_details_simple (element_class, "Direct3D video sink",
|
||||||
"Sink/Video",
|
"Sink/Video",
|
||||||
|
@ -531,10 +528,7 @@ gst_d3dvideosink_create_shared_hidden_window (GstD3DVideoSink * sink)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
CloseHandle (shared.hidden_window_created_signal);
|
CloseHandle (shared.hidden_window_created_signal);
|
||||||
/*
|
|
||||||
if (!shared.d3ddev)
|
|
||||||
goto failed;
|
|
||||||
*/
|
|
||||||
GST_DEBUG ("Successfully created Direct3D hidden window, handle: %p",
|
GST_DEBUG ("Successfully created Direct3D hidden window, handle: %p",
|
||||||
shared.hidden_window_handle);
|
shared.hidden_window_handle);
|
||||||
|
|
||||||
|
@ -639,7 +633,9 @@ SharedHiddenWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
shared.device_lost_sink = NULL;
|
shared.device_lost_sink = NULL;
|
||||||
GST_DEBUG ("Initializing Direct3D");
|
GST_DEBUG ("Initializing Direct3D");
|
||||||
|
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
|
||||||
gst_d3dvideosink_initialize_d3d_device (sink);
|
gst_d3dvideosink_initialize_d3d_device (sink);
|
||||||
|
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
||||||
GST_DEBUG ("Direct3D initialization complete");
|
GST_DEBUG ("Direct3D initialization complete");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -664,9 +660,11 @@ SharedHiddenWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
/* Did we receive a message to check if the device is available again? */
|
/* Did we receive a message to check if the device is available again? */
|
||||||
if (wParam == IDT_DEVICELOST) {
|
if (wParam == IDT_DEVICELOST) {
|
||||||
|
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
|
||||||
/* This will synchronously call SharedHiddenWndProc() because this thread is the one that created the window. */
|
/* This will synchronously call SharedHiddenWndProc() because this thread is the one that created the window. */
|
||||||
SendMessage (hWnd, WM_DIRECTX_D3D_DEVICELOST, 0,
|
SendMessage (hWnd, WM_DIRECTX_D3D_DEVICELOST, 0,
|
||||||
(LPARAM) shared.device_lost_sink);
|
(LPARAM) shared.device_lost_sink);
|
||||||
|
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -736,6 +734,9 @@ WndProcHook (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
GstD3DVideoSink *sink =
|
GstD3DVideoSink *sink =
|
||||||
(GstD3DVideoSink *) GetProp (hWnd, TEXT ("GstD3DVideoSink"));
|
(GstD3DVideoSink *) GetProp (hWnd, TEXT ("GstD3DVideoSink"));
|
||||||
|
|
||||||
|
if (!sink)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case WM_ERASEBKGND:
|
case WM_ERASEBKGND:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -802,6 +803,8 @@ static void
|
||||||
gst_d3dvideosink_wnd_proc (GstD3DVideoSink * sink, HWND hWnd, UINT message,
|
gst_d3dvideosink_wnd_proc (GstD3DVideoSink * sink, HWND hWnd, UINT message,
|
||||||
WPARAM wParam, LPARAM lParam)
|
WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
if (!sink)
|
||||||
|
return;
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case WM_COPYDATA:
|
case WM_COPYDATA:
|
||||||
{
|
{
|
||||||
|
@ -1069,12 +1072,18 @@ gst_d3dvideosink_set_window_handle (GstXOverlay * overlay, guintptr window_id)
|
||||||
|
|
||||||
/* If we're already playing/paused, then we need to lock the swap chain, and recreate it with the new window. */
|
/* If we're already playing/paused, then we need to lock the swap chain, and recreate it with the new window. */
|
||||||
if (sink->d3ddev != NULL) {
|
if (sink->d3ddev != NULL) {
|
||||||
|
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
|
||||||
/* Close our existing window if there is one */
|
/* Close our existing window if there is one */
|
||||||
gst_d3dvideosink_close_window (sink);
|
gst_d3dvideosink_close_window (sink);
|
||||||
/* Save our window id */
|
/* Save our window id */
|
||||||
sink->window_handle = hWnd;
|
sink->window_handle = hWnd;
|
||||||
gst_d3dvideosink_set_window_for_renderer (sink);
|
gst_d3dvideosink_set_window_for_renderer (sink);
|
||||||
gst_d3dvideosink_notify_device_resize (sink);
|
sink->window_closed = FALSE;
|
||||||
|
|
||||||
|
gst_d3dvideosink_notify_device_reinit (sink);
|
||||||
|
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
||||||
|
//gst_d3dvideosink_notify_device_init(sink);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sink->window_handle = hWnd;
|
sink->window_handle = hWnd;
|
||||||
}
|
}
|
||||||
|
@ -1314,8 +1323,6 @@ GST_D3DVIDEOSINK_SHARED_D3D_HOOK_UNLOCK GST_D3DVIDEOSINK_SHARED_D3D_UNLOCK}
|
||||||
static void
|
static void
|
||||||
gst_d3dvideosink_remove_window_for_renderer (GstD3DVideoSink * sink)
|
gst_d3dvideosink_remove_window_for_renderer (GstD3DVideoSink * sink)
|
||||||
{
|
{
|
||||||
//GST_D3DVIDEOSINK_SHARED_D3D_LOCK
|
|
||||||
//GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK(sink);
|
|
||||||
{
|
{
|
||||||
GST_DEBUG ("Removing custom rendering window procedure");
|
GST_DEBUG ("Removing custom rendering window procedure");
|
||||||
if (!sink->is_new_window && sink->window_handle) {
|
if (!sink->is_new_window && sink->window_handle) {
|
||||||
|
@ -1342,8 +1349,6 @@ gst_d3dvideosink_remove_window_for_renderer (GstD3DVideoSink * sink)
|
||||||
/* Remove the property associating our sink with the window */
|
/* Remove the property associating our sink with the window */
|
||||||
RemoveProp (sink->window_handle, TEXT ("GstD3DVideoSink"));
|
RemoveProp (sink->window_handle, TEXT ("GstD3DVideoSink"));
|
||||||
}
|
}
|
||||||
//GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK(sink);
|
|
||||||
//GST_D3DVIDEOSINK_SHARED_D3D_UNLOCK
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2034,9 +2039,6 @@ gst_d3dvideosink_initialize_d3d_device (GstD3DVideoSink * sink)
|
||||||
/* Get the current size of the window */
|
/* Get the current size of the window */
|
||||||
gst_d3dvideosink_window_size (sink, &width, &height);
|
gst_d3dvideosink_window_size (sink, &width, &height);
|
||||||
|
|
||||||
|
|
||||||
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
|
|
||||||
|
|
||||||
if (!shared.d3d) {
|
if (!shared.d3d) {
|
||||||
GST_WARNING ("Direct3D object has not been initialized");
|
GST_WARNING ("Direct3D object has not been initialized");
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -2195,41 +2197,10 @@ gst_d3dvideosink_initialize_d3d_device (GstD3DVideoSink * sink)
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/*success:*/
|
/*success:*/
|
||||||
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
//GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
error:
|
error:
|
||||||
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
//GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_d3dvideosink_resize_swap_chain (GstD3DVideoSink * sink, gint width,
|
|
||||||
gint height)
|
|
||||||
{
|
|
||||||
if (width <= 0 || height <= 0 || width > GetSystemMetrics (SM_CXFULLSCREEN)
|
|
||||||
|| height > GetSystemMetrics (SM_CYFULLSCREEN)) {
|
|
||||||
GST_DEBUG ("Invalid size");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (!shared.d3d || !sink->d3ddev) {
|
|
||||||
GST_DEBUG_OBJECT (sink, "Direct3D device not initialized.");
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (sink, "Resizing Direct3D swap chain for sink %p to %dx%d",
|
|
||||||
sink, width, height);
|
|
||||||
/* actually recreates the device + associated surfaces
|
|
||||||
must be called from thread that created the device */
|
|
||||||
if (!gst_d3dvideosink_notify_device_resize (sink))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
|
|
||||||
/* success:*/
|
|
||||||
GST_LOG_OBJECT (sink, "Direct3D swap chain successfully resized");
|
|
||||||
return TRUE;
|
|
||||||
error:
|
|
||||||
GST_ERROR_OBJECT (sink, "Error attempting to resize the Direct3D swap chain");
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2244,10 +2215,10 @@ gst_d3dvideosink_notify_device_init (GstD3DVideoSink * sink)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_d3dvideosink_notify_device_resize (GstD3DVideoSink * sink)
|
gst_d3dvideosink_notify_device_reinit (GstD3DVideoSink * sink)
|
||||||
{
|
{
|
||||||
if (sink->window_handle) {
|
if (sink->window_handle) {
|
||||||
SendMessage (shared.hidden_window_handle, WM_DIRECTX_D3D_RESIZE, 0,
|
SendMessage (shared.hidden_window_handle, WM_DIRECTX_D3D_DEVICELOST, 0,
|
||||||
(LPARAM) sink);
|
(LPARAM) sink);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -2295,7 +2266,6 @@ gst_d3dvideosink_device_lost (GstD3DVideoSink * sink)
|
||||||
{
|
{
|
||||||
/* Must be called from hidden window's message loop! */
|
/* Must be called from hidden window's message loop! */
|
||||||
|
|
||||||
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
|
|
||||||
{
|
{
|
||||||
if (shared.device_lost)
|
if (shared.device_lost)
|
||||||
GST_DEBUG ("Direct3D device lost");
|
GST_DEBUG ("Direct3D device lost");
|
||||||
|
@ -2343,18 +2313,15 @@ gst_d3dvideosink_device_lost (GstD3DVideoSink * sink)
|
||||||
|
|
||||||
/*success:*/
|
/*success:*/
|
||||||
GST_DEBUG ("Direct3D device has successfully been reset.");
|
GST_DEBUG ("Direct3D device has successfully been reset.");
|
||||||
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
error:
|
error:
|
||||||
GST_DEBUG ("Unable to successfully reset the Direct3D device.");
|
GST_DEBUG ("Unable to successfully reset the Direct3D device.");
|
||||||
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_d3dvideosink_release_d3d_device (GstD3DVideoSink * sink)
|
gst_d3dvideosink_release_d3d_device (GstD3DVideoSink * sink)
|
||||||
{
|
{
|
||||||
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
|
|
||||||
if (sink->d3ddev) {
|
if (sink->d3ddev) {
|
||||||
int ref_count;
|
int ref_count;
|
||||||
ref_count = IDirect3DDevice9_Release (sink->d3ddev);
|
ref_count = IDirect3DDevice9_Release (sink->d3ddev);
|
||||||
|
@ -2369,7 +2336,7 @@ gst_d3dvideosink_release_d3d_device (GstD3DVideoSink * sink)
|
||||||
GST_DEBUG_OBJECT (sink,
|
GST_DEBUG_OBJECT (sink,
|
||||||
"Direct3D offscreen surface released. Reference count: %d", ref_count);
|
"Direct3D offscreen surface released. Reference count: %d", ref_count);
|
||||||
}
|
}
|
||||||
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
//GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2391,7 +2358,9 @@ gst_d3dvideosink_release_direct3d (GstD3DVideoSink * sink)
|
||||||
if (shared.element_count > 0)
|
if (shared.element_count > 0)
|
||||||
goto success;
|
goto success;
|
||||||
|
|
||||||
|
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
|
||||||
gst_d3dvideosink_release_d3d_device (sink);
|
gst_d3dvideosink_release_d3d_device (sink);
|
||||||
|
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
|
||||||
if (shared.d3d) {
|
if (shared.d3d) {
|
||||||
int ref_count;
|
int ref_count;
|
||||||
ref_count = IDirect3D9_Release (shared.d3d);
|
ref_count = IDirect3D9_Release (shared.d3d);
|
||||||
|
|
Loading…
Reference in a new issue