mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 15:51:11 +00:00
d3dvideosink: rework locking for devices lost
This commit is contained in:
parent
bd68bd61da
commit
e1651e9b65
2 changed files with 56 additions and 44 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue