summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAndoni Morales Alastruey <ylatuya@gmail.com>2012-06-19 20:03:02 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2012-06-26 09:39:36 +0200
commite1651e9b659daaaf0e7dfae7b6fc438db4b30e6b (patch)
treeb3919b2f819ec8454cdbf6b1f8c46dafd71d7a75 /sys
parentbd68bd61da24f7050a6bc5d2a9a59cad4f0d2148 (diff)
downloadgstreamer-plugins-bad-e1651e9b659daaaf0e7dfae7b6fc438db4b30e6b.tar.gz
d3dvideosink: rework locking for devices lost
Diffstat (limited to 'sys')
-rw-r--r--sys/d3dvideosink/d3dvideosink.c93
-rw-r--r--sys/d3dvideosink/d3dvideosink.h7
2 files changed, 56 insertions, 44 deletions
diff --git a/sys/d3dvideosink/d3dvideosink.c b/sys/d3dvideosink/d3dvideosink.c
index 4aa76110e..a22a01940 100644
--- a/sys/d3dvideosink/d3dvideosink.c
+++ b/sys/d3dvideosink/d3dvideosink.c
@@ -319,7 +319,7 @@ gst_d3dvideosink_init (GstD3DVideoSink * sink)
{
gst_d3dvideosink_clear (sink);
- sink->d3d_swap_chain_lock = g_mutex_new ();
+ sink->d3d_device_lock = g_mutex_new ();
sink->par = g_new0 (GValue, 1);
g_value_init (sink->par, GST_TYPE_FRACTION);
@@ -341,8 +341,8 @@ gst_d3dvideosink_finalize (GObject * gobject)
sink->par = NULL;
}
- g_mutex_free (sink->d3d_swap_chain_lock);
- sink->d3d_swap_chain_lock = NULL;
+ g_mutex_free (sink->d3d_device_lock);
+ sink->d3d_device_lock = NULL;
G_OBJECT_CLASS (parent_class)->finalize (gobject);
}
@@ -588,6 +588,7 @@ gst_d3dvideosink_shared_hidden_window_thread (GstD3DVideoSink * sink)
shared.hidden_window_handle = hWnd;
shared.device_lost_timer = 0;
+ shared.device_lost = FALSE;
gst_d3dvideosink_shared_hidden_window_created (sink);
@@ -643,27 +644,29 @@ 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");
+ if (!gst_d3dvideosink_initialize_d3d_device (sink))
+ gst_d3dvideosink_notify_device_lost(sink);
+ else
+ GST_DEBUG ("Direct3D initialization complete");
break;
}
case WM_DIRECTX_D3D_INIT_DEVICELOST:
{
- if (!shared.device_lost) {
+ if (shared.device_lost)
+ break;
- shared.device_lost = TRUE;
- shared.device_lost_sink = sink;
+ shared.device_lost = TRUE;
+ GST_D3DVIDEOSINK_D3D_DEVICE_LOCK (sink);
- /* Handle device lost by creating a timer and posting WM_D3D_DEVICELOST twice a second */
- /* Create a timer to periodically check the d3d device and attempt to recreate it */
- shared.device_lost_timer = SetTimer (hWnd, IDT_DEVICELOST, 500, NULL);
- /* Try it once immediately */
- SendMessage (hWnd, WM_DIRECTX_D3D_DEVICELOST, 0, (LPARAM) sink);
- }
+ /* Handle device lost by creating a timer and posting WM_D3D_DEVICELOST twice a second */
+ /* Create a timer to periodically check the d3d device and attempt to recreate it */
+ shared.device_lost_timer = SetTimer (hWnd, IDT_DEVICELOST, 500, NULL);
+ shared.device_lost_sink = sink;
+
+ /* Try it once immediately */
+ SendMessage (hWnd, WM_DIRECTX_D3D_DEVICELOST, 0, (LPARAM) sink);
break;
}
case WM_TIMER:
@@ -683,21 +686,24 @@ SharedHiddenWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
}
case WM_DIRECTX_D3D_END_DEVICELOST:
{
- if (shared.device_lost) {
- /* gst_d3dvideosink_notify_device_reset() sends this message. */
- if (shared.device_lost_timer != 0)
- KillTimer (hWnd, shared.device_lost_timer);
+ if (!shared.device_lost)
+ break;
- shared.device_lost_timer = 0;
- shared.device_lost = FALSE;
+ /* gst_d3dvideosink_notify_device_reset() sends this message. */
+ if (shared.device_lost_timer != 0)
+ KillTimer (hWnd, shared.device_lost_timer);
- /* Refresh the video with the last buffer */
- gst_d3dvideosink_update_all (sink);
+ shared.device_lost_timer = 0;
+ shared.device_lost = FALSE;
- /* Then redraw just in case we don't have a last buffer */
- gst_d3dvideosink_refresh_all (sink);
+ GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
+
+ /* Refresh the video with the last buffer */
+ gst_d3dvideosink_update_all (sink);
+
+ /* Then redraw just in case we don't have a last buffer */
+ gst_d3dvideosink_refresh_all (sink);
- }
shared.device_lost_sink = NULL;
break;
}
@@ -1078,9 +1084,9 @@ gst_d3dvideosink_set_window_handle (GstVideoOverlay * overlay, guintptr window_i
return;
}
+ GST_D3DVIDEOSINK_D3D_DEVICE_LOCK (sink);
/* 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 */
@@ -1089,14 +1095,12 @@ gst_d3dvideosink_set_window_handle (GstVideoOverlay * overlay, guintptr window_i
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;
}
-/*success:*/
+ GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
+
GST_DEBUG_OBJECT (sink, "Direct3D window id successfully changed to %p",
hWnd);
@@ -1375,13 +1379,17 @@ gst_d3dvideosink_prepare_window (GstD3DVideoSink * sink)
* and create (and use) our own window, if we didn't create
* one before */
if (sink->window_handle && sink->is_new_window) {
- gst_d3dvideosink_release_d3d_device (sink);
+ GST_D3DVIDEOSINK_D3D_DEVICE_LOCK(sink);
+ gst_d3dvideosink_release_d3d_device(sink);
+ GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK(sink);
} else if (sink->window_handle) {
gst_d3dvideosink_set_window_for_renderer (sink);
} else {
gst_d3dvideosink_create_default_window (sink);
}
+ GST_D3DVIDEOSINK_D3D_DEVICE_LOCK(sink);
gst_d3dvideosink_notify_device_init (sink);
+ GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK(sink);
}
static GstStateChangeReturn
@@ -1625,7 +1633,8 @@ gst_d3dvideosink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
GstD3DVideoSink *sink = GST_D3DVIDEOSINK (vsink);
LPDIRECT3DSURFACE9 drawSurface = NULL;
- GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
+ if (!GST_D3DVIDEOSINK_D3D_DEVICE_TRYLOCK (sink))
+ return GST_FLOW_OK;
if (!sink->d3ddev) {
if (!shared.device_lost) {
GST_ERROR_OBJECT (sink, "No Direct3D device has been created, stopping");
@@ -1747,7 +1756,7 @@ gst_d3dvideosink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
IDirect3DDevice9_EndScene (sink->d3ddev);
}
success:
- GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
+ GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
gst_d3dvideosink_refresh (sink);
return GST_FLOW_OK;
#if 0
@@ -1760,7 +1769,7 @@ wrong_state:
/* return GST_FLOW_UNEXPECTED; */
#endif
error:
- GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
+ GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
return GST_FLOW_ERROR;
}
@@ -1768,7 +1777,8 @@ error:
static gboolean
gst_d3dvideosink_refresh (GstD3DVideoSink * sink)
{
- GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
+ if (!GST_D3DVIDEOSINK_D3D_DEVICE_TRYLOCK (sink))
+ return TRUE;
{
HRESULT hr;
LPDIRECT3DSURFACE9 backBuffer;
@@ -1823,10 +1833,10 @@ gst_d3dvideosink_refresh (GstD3DVideoSink * sink)
}
/*success:*/
- GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
+ GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
return TRUE;
error:
- GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
+ GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
return FALSE;
}
@@ -2361,9 +2371,10 @@ gst_d3dvideosink_release_direct3d (GstD3DVideoSink * sink)
if (shared.element_count > 0)
goto success;
- GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK (sink);
+ GST_D3DVIDEOSINK_D3D_DEVICE_LOCK (sink);
gst_d3dvideosink_release_d3d_device (sink);
- GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK (sink);
+ GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK (sink);
+
if (shared.d3d) {
int ref_count;
ref_count = IDirect3D9_Release (shared.d3d);
diff --git a/sys/d3dvideosink/d3dvideosink.h b/sys/d3dvideosink/d3dvideosink.h
index 67877fa8b..6d9b4957c 100644
--- a/sys/d3dvideosink/d3dvideosink.h
+++ b/sys/d3dvideosink/d3dvideosink.h
@@ -63,8 +63,9 @@ G_BEGIN_DECLS
typedef struct _GstD3DVideoSink GstD3DVideoSink;
typedef struct _GstD3DVideoSinkClass GstD3DVideoSinkClass;
-#define GST_D3DVIDEOSINK_SWAP_CHAIN_LOCK(sink) g_mutex_lock (GST_D3DVIDEOSINK (sink)->d3d_swap_chain_lock);
-#define GST_D3DVIDEOSINK_SWAP_CHAIN_UNLOCK(sink) g_mutex_unlock (GST_D3DVIDEOSINK (sink)->d3d_swap_chain_lock);
+#define GST_D3DVIDEOSINK_D3D_DEVICE_LOCK(sink) g_mutex_lock (GST_D3DVIDEOSINK (sink)->d3d_device_lock)
+#define GST_D3DVIDEOSINK_D3D_DEVICE_TRYLOCK(sink) g_mutex_trylock (GST_D3DVIDEOSINK (sink)->d3d_device_lock)
+#define GST_D3DVIDEOSINK_D3D_DEVICE_UNLOCK(sink) g_mutex_unlock (GST_D3DVIDEOSINK (sink)->d3d_device_lock)
struct _GstD3DVideoSink
{
@@ -99,7 +100,7 @@ struct _GstD3DVideoSink
WNDPROC prevWndProc;
gboolean is_hooked;
- GMutex *d3d_swap_chain_lock;
+ GMutex *d3d_device_lock;
LPDIRECT3DSURFACE9 d3d_offscreen_surface;
LPDIRECT3DDEVICE9 d3ddev;
D3DPRESENT_PARAMETERS d3dpp;