d3dvideosink: fix regression setting window handle in pause/play

https://bugzilla.gnome.org/show_bug.cgi?id=656905
This commit is contained in:
Carsten Kroll 2012-03-15 22:12:59 +01:00 committed by Tim-Philipp Müller
parent aca69cbf63
commit 6f3ea8e67b

View file

@ -63,7 +63,6 @@ struct _GstD3DVideoSinkHookData
static GstD3DVideoSinkShared shared;
/* Define a shared lock to synchronize the creation/destruction of the d3d device */
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;
/* Hold a reference to our dll's HINSTANCE */
static HINSTANCE g_hinstDll = NULL;
@ -155,12 +154,11 @@ static void gst_d3dvideosink_remove_window_for_renderer (GstD3DVideoSink *
sink);
static gboolean gst_d3dvideosink_initialize_direct3d (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_lost (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_release_d3d_device (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);
gst_element_class_add_static_pad_template (element_class,
&sink_template);
gst_element_class_add_static_pad_template (element_class, &sink_template);
gst_element_class_set_details_simple (element_class, "Direct3D video sink",
"Sink/Video",
@ -531,10 +528,7 @@ gst_d3dvideosink_create_shared_hidden_window (GstD3DVideoSink * sink)
goto failed;
CloseHandle (shared.hidden_window_created_signal);
/*
if (!shared.d3ddev)
goto failed;
*/
GST_DEBUG ("Successfully created Direct3D hidden window, handle: %p",
shared.hidden_window_handle);
@ -639,7 +633,9 @@ SharedHiddenWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
shared.device_lost_sink = NULL;
GST_DEBUG ("Initializing Direct3D");
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
gst_d3dvideosink_initialize_d3d_device (sink);
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
GST_DEBUG ("Direct3D initialization complete");
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? */
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. */
SendMessage (hWnd, WM_DIRECTX_D3D_DEVICELOST, 0,
(LPARAM) shared.device_lost_sink);
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
return 0;
}
break;
@ -736,6 +734,9 @@ WndProcHook (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
GstD3DVideoSink *sink =
(GstD3DVideoSink *) GetProp (hWnd, TEXT ("GstD3DVideoSink"));
if (!sink)
return FALSE;
switch (message) {
case WM_ERASEBKGND:
return TRUE;
@ -802,6 +803,8 @@ static void
gst_d3dvideosink_wnd_proc (GstD3DVideoSink * sink, HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
if (!sink)
return;
switch (message) {
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 (sink->d3ddev != NULL) {
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
/* Close our existing window if there is one */
gst_d3dvideosink_close_window (sink);
/* Save our window id */
sink->window_handle = hWnd;
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 {
sink->window_handle = hWnd;
}
@ -1314,8 +1323,6 @@ GST_D3DVIDEOSINK_SHARED_D3D_HOOK_UNLOCK GST_D3DVIDEOSINK_SHARED_D3D_UNLOCK}
static void
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");
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 */
RemoveProp (sink->window_handle, TEXT ("GstD3DVideoSink"));
}
//GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK(sink);
//GST_D3DVIDEOSINK_SHARED_D3D_UNLOCK
}
static void
@ -1373,7 +1378,7 @@ gst_d3dvideosink_change_state (GstElement * element, GstStateChange transition)
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
if (!gst_d3dvideosink_initialize_direct3d (sink))
return GST_STATE_CHANGE_FAILURE;
return GST_STATE_CHANGE_FAILURE;
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
break;
@ -2034,9 +2039,6 @@ gst_d3dvideosink_initialize_d3d_device (GstD3DVideoSink * sink)
/* Get the current size of the window */
gst_d3dvideosink_window_size (sink, &width, &height);
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
if (!shared.d3d) {
GST_WARNING ("Direct3D object has not been initialized");
goto error;
@ -2195,41 +2197,10 @@ gst_d3dvideosink_initialize_d3d_device (GstD3DVideoSink * sink)
//}
/*success:*/
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
//GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
return TRUE;
error:
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");
//GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
return FALSE;
}
@ -2244,10 +2215,10 @@ gst_d3dvideosink_notify_device_init (GstD3DVideoSink * sink)
}
static gboolean
gst_d3dvideosink_notify_device_resize (GstD3DVideoSink * sink)
gst_d3dvideosink_notify_device_reinit (GstD3DVideoSink * sink)
{
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);
}
return TRUE;
@ -2295,7 +2266,6 @@ gst_d3dvideosink_device_lost (GstD3DVideoSink * sink)
{
/* Must be called from hidden window's message loop! */
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
{
if (shared.device_lost)
GST_DEBUG ("Direct3D device lost");
@ -2343,18 +2313,15 @@ gst_d3dvideosink_device_lost (GstD3DVideoSink * sink)
/*success:*/
GST_DEBUG ("Direct3D device has successfully been reset.");
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
return TRUE;
error:
GST_DEBUG ("Unable to successfully reset the Direct3D device.");
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
return FALSE;
}
static gboolean
gst_d3dvideosink_release_d3d_device (GstD3DVideoSink * sink)
{
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
if (sink->d3ddev) {
int ref_count;
ref_count = IDirect3DDevice9_Release (sink->d3ddev);
@ -2369,7 +2336,7 @@ gst_d3dvideosink_release_d3d_device (GstD3DVideoSink * sink)
GST_DEBUG_OBJECT (sink,
"Direct3D offscreen surface released. Reference count: %d", ref_count);
}
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
//GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
return TRUE;
}
@ -2391,7 +2358,9 @@ gst_d3dvideosink_release_direct3d (GstD3DVideoSink * sink)
if (shared.element_count > 0)
goto success;
GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
gst_d3dvideosink_release_d3d_device (sink);
GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
if (shared.d3d) {
int ref_count;
ref_count = IDirect3D9_Release (shared.d3d);