From: Aaron Boxer Date: Sat, 7 Dec 2019 20:51:28 +0000 (-0600) Subject: d3dvideosink: use thread pool to handle events from hidden window event queue X-Git-Tag: 1.19.3~507^2~2523 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eff0117b5a22a4cbe3d2a128708155e0bafb0280;p=platform%2Fupstream%2Fgstreamer.git d3dvideosink: use thread pool to handle events from hidden window event queue window event queue now does not lock on the class lock, so we can now shut it down without releasing the class lock, thus avoiding a potential race when stopping the sink. --- diff --git a/sys/d3dvideosink/d3dhelpers.c b/sys/d3dvideosink/d3dhelpers.c index 80811aa..3e4bbcc 100644 --- a/sys/d3dvideosink/d3dhelpers.c +++ b/sys/d3dvideosink/d3dhelpers.c @@ -57,6 +57,8 @@ static void d3d_class_notify_device_lost (GstD3DVideoSink * sink); static void d3d_class_display_device_destroy (GstD3DVideoSinkClass * klass); static gboolean d3d_class_display_device_create (GstD3DVideoSinkClass * klass, UINT adapter); +static void d3d_class_hidden_window_message_queue (gpointer data, + gpointer user_data); static LRESULT APIENTRY d3d_wnd_proc_internal (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -72,6 +74,12 @@ static gint WM_D3DVIDEO_NOTIFY_DEVICE_LOST = 0; #define WM_QUIT_THREAD WM_USER+0 +typedef struct +{ + gint window_message_id; + guint create_count; +} GstD3DVideoSinkEvent; + /* Helpers */ #define ERROR_CHECK_HR(hr) \ @@ -2666,7 +2674,13 @@ static void d3d_class_notify_device_lost (GstD3DVideoSink * sink) { GstD3DVideoSinkClass *klass = GST_D3DVIDEOSINK_GET_CLASS (sink); - PostMessage (klass->d3d.hidden_window, WM_D3DVIDEO_NOTIFY_DEVICE_LOST, 0, 0); + GstD3DVideoSinkEvent *evt = g_new0 (GstD3DVideoSinkEvent, 1); + + evt->window_message_id = IDT_DEVICE_RESET_TIMER; + evt->create_count = klass->create_count; + gst_element_call_async (GST_ELEMENT (klass), + (GstElementCallAsyncFunc) d3d_class_hidden_window_message_queue, evt, + g_free); } static void @@ -2734,29 +2748,61 @@ end: /* Hidden Window Loop Thread */ +static void +d3d_class_hidden_window_message_queue (gpointer data, gpointer user_data) +{ + guint id = 0; + GstD3DVideoSinkClass *klass = (GstD3DVideoSinkClass *) data; + GstD3DVideoSinkEvent *evt = (GstD3DVideoSinkEvent *) user_data; + + if (!klass || !evt) + return; + + switch (evt->window_message_id) { + case IDT_DEVICE_RESET_TIMER: + LOCK_CLASS (NULL, klass); + /* make sure this event does not originate from old class */ + if (evt->create_count == klass->create_count) + d3d_class_reset_display_device (klass); + UNLOCK_CLASS (NULL, klass); + break; + default: + if (id == WM_D3DVIDEO_NOTIFY_DEVICE_LOST) { + LOCK_CLASS (NULL, klass); + /* make sure this event does not originate from old class */ + if (evt->create_count == klass->create_count) + d3d_class_notify_device_lost_all (klass); + UNLOCK_CLASS (NULL, klass); + } + break; + } +} + static LRESULT APIENTRY D3DHiddenWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + GstD3DVideoSinkClass *klass = + (GstD3DVideoSinkClass *) GetWindowLongPtr (hWnd, GWLP_USERDATA); + GstD3DVideoSinkEvent *evt; + switch (message) { case WM_TIMER: switch (wParam) { case IDT_DEVICE_RESET_TIMER: - d3d_class_reset_display_device ((GstD3DVideoSinkClass *) - GetWindowLongPtr (hWnd, GWLP_USERDATA)); + evt = g_new0 (GstD3DVideoSinkEvent, 1); + evt->window_message_id = IDT_DEVICE_RESET_TIMER; + evt->create_count = klass->create_count; + gst_element_call_async (GST_ELEMENT (klass), + (GstElementCallAsyncFunc) d3d_class_hidden_window_message_queue, + evt, g_free); break; - default:; } return 0; case WM_DESTROY: PostQuitMessage (0); return 0; default: - /* non constants */ - if (message == WM_D3DVIDEO_NOTIFY_DEVICE_LOST) { - d3d_class_notify_device_lost_all ((GstD3DVideoSinkClass *) - GetWindowLongPtr (hWnd, GWLP_USERDATA)); - return 0; - } + break; } return DefWindowProc (hWnd, message, wParam, lParam); diff --git a/sys/d3dvideosink/d3dvideosink.h b/sys/d3dvideosink/d3dvideosink.h index 67ac6c0..807f3be 100644 --- a/sys/d3dvideosink/d3dvideosink.h +++ b/sys/d3dvideosink/d3dvideosink.h @@ -74,6 +74,9 @@ struct _GstD3DVideoSinkClass GstVideoSinkClass parent_class; GstD3DDataClass d3d; GRecMutex lock; + /* this count is incremented each time the sink is destroyed, so that + * old queue events can be ignored */ + guint create_count; }; #define LOCK_SINK(sink) G_STMT_START { \