Zebediah Figura : winegstreamer: Catch errors while waiting for pin connection.

Alexandre Julliard julliard at winehq.org
Thu Jan 2 16:04:21 CST 2020


Module: wine
Branch: master
Commit: a191a0c23a62288ba8906283c5727c5e5a2ccca4
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a191a0c23a62288ba8906283c5727c5e5a2ccca4

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Wed Jan  1 20:28:41 2020 -0600

winegstreamer: Catch errors while waiting for pin connection.

In the event that the user is missing GStreamer plugins this may allow the
program to terminate gracefully rather than hanging in the init_gst() callback.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winegstreamer/gstdemux.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index e67efd58eb..7ae70d0a73 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -68,7 +68,7 @@ struct gstdemux
     GstBus *bus;
     guint64 start, nextofs, nextpullofs, stop;
     ALLOCATOR_PROPERTIES props;
-    HANDLE no_more_pads_event, duration_event;
+    HANDLE no_more_pads_event, duration_event, error_event;
 
     HANDLE push_thread;
 
@@ -1139,6 +1139,7 @@ static GstBusSyncReply watch_bus(GstBus *bus, GstMessage *msg, gpointer data)
         ERR("%s\n", dbg_info);
         g_error_free(err);
         g_free(dbg_info);
+        SetEvent(filter->error_event);
         break;
     case GST_MESSAGE_WARNING:
         gst_message_parse_warning(msg, &err, &dbg_info);
@@ -1225,6 +1226,7 @@ static void gstdemux_destroy(struct strmbase_filter *iface)
 
     CloseHandle(filter->no_more_pads_event);
     CloseHandle(filter->duration_event);
+    CloseHandle(filter->error_event);
 
     /* Don't need to clean up output pins, disconnecting input pin will do that */
     if (filter->sink.pin.peer)
@@ -1498,12 +1500,14 @@ static BOOL gstdecoder_init_gst(struct gstdemux *filter)
     for (i = 0; i < filter->cStreams; ++i)
     {
         struct gstdemux_source *pin = filter->ppPins[i];
+        const HANDLE events[2] = {pin->caps_event, filter->error_event};
 
         pin->seek.llDuration = pin->seek.llStop = duration / 100;
         pin->seek.llCurrent = 0;
         if (!pin->seek.llDuration)
             pin->seek.dwCapabilities = 0;
-        WaitForSingleObject(pin->caps_event, INFINITE);
+        if (WaitForMultipleObjects(2, events, FALSE, INFINITE))
+            return FALSE;
     }
 
     filter->ignore_flush = TRUE;
@@ -1536,6 +1540,7 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
     strmbase_sink_init(&object->sink, &object->filter, wcsInputPinName, &sink_ops, NULL);
 
     object->no_more_pads_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+    object->error_event = CreateEventW(NULL, TRUE, FALSE, NULL);
     object->init_gst = gstdecoder_init_gst;
     *phr = S_OK;
 
@@ -2171,6 +2176,7 @@ static BOOL wave_parser_init_gst(struct gstdemux *filter)
     struct gstdemux_source *pin;
     GstElement *element;
     LONGLONG duration;
+    HANDLE events[2];
     int ret;
 
     if (!(element = gst_element_factory_make("wavparse", NULL)))
@@ -2214,7 +2220,10 @@ static BOOL wave_parser_init_gst(struct gstdemux *filter)
     if (!pin->seek.llDuration)
         pin->seek.dwCapabilities = 0;
 
-    WaitForSingleObject(pin->caps_event, INFINITE);
+    events[0] = pin->caps_event;
+    events[1] = filter->error_event;
+    if (WaitForMultipleObjects(2, events, FALSE, INFINITE))
+        return FALSE;
 
     filter->ignore_flush = TRUE;
     gst_element_set_state(filter->container, GST_STATE_READY);
@@ -2246,6 +2255,7 @@ IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr)
     strmbase_filter_init(&object->filter, outer, &CLSID_WAVEParser, &filter_ops);
     strmbase_sink_init(&object->sink, &object->filter, sink_name, &wave_parser_sink_ops, NULL);
     object->init_gst = wave_parser_init_gst;
+    object->error_event = CreateEventW(NULL, TRUE, FALSE, NULL);
     *phr = S_OK;
 
     TRACE("Created WAVE parser %p.\n", object);
@@ -2311,12 +2321,14 @@ static BOOL avi_splitter_init_gst(struct gstdemux *filter)
     for (i = 0; i < filter->cStreams; ++i)
     {
         struct gstdemux_source *pin = filter->ppPins[i];
+        const HANDLE events[2] = {pin->caps_event, filter->error_event};
 
         pin->seek.llDuration = pin->seek.llStop = duration / 100;
         pin->seek.llCurrent = 0;
         if (!pin->seek.llDuration)
             pin->seek.dwCapabilities = 0;
-        WaitForSingleObject(pin->caps_event, INFINITE);
+        if (WaitForMultipleObjects(2, events, FALSE, INFINITE))
+            return FALSE;
     }
 
     filter->ignore_flush = TRUE;
@@ -2349,6 +2361,7 @@ IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr)
     strmbase_filter_init(&object->filter, outer, &CLSID_AviSplitter, &filter_ops);
     strmbase_sink_init(&object->sink, &object->filter, sink_name, &avi_splitter_sink_ops, NULL);
     object->no_more_pads_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+    object->error_event = CreateEventW(NULL, TRUE, FALSE, NULL);
     object->init_gst = avi_splitter_init_gst;
     *phr = S_OK;
 
@@ -2383,6 +2396,7 @@ static BOOL mpeg_splitter_init_gst(struct gstdemux *filter)
     struct gstdemux_source *pin;
     GstElement *element;
     LONGLONG duration;
+    HANDLE events[2];
     int ret;
 
     if (!(element = gst_element_factory_make("mpegaudioparse", NULL)))
@@ -2419,14 +2433,20 @@ static BOOL mpeg_splitter_init_gst(struct gstdemux *filter)
         return FALSE;
     }
 
-    WaitForSingleObject(filter->duration_event, INFINITE);
+    events[0] = filter->duration_event;
+    events[1] = filter->error_event;
+    if (WaitForMultipleObjects(2, events, FALSE, INFINITE))
+        return FALSE;
+
     gst_pad_query_duration(pin->their_src, GST_FORMAT_TIME, &duration);
     pin->seek.llDuration = pin->seek.llStop = duration / 100;
     pin->seek.llCurrent = 0;
     if (!pin->seek.llDuration)
         pin->seek.dwCapabilities = 0;
 
-    WaitForSingleObject(pin->caps_event, INFINITE);
+    events[0] = pin->caps_event;
+    if (WaitForMultipleObjects(2, events, FALSE, INFINITE))
+        return FALSE;
 
     filter->ignore_flush = TRUE;
     gst_element_set_state(filter->container, GST_STATE_READY);
@@ -2486,6 +2506,7 @@ IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr)
     object->IAMStreamSelect_iface.lpVtbl = &stream_select_vtbl;
 
     object->duration_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+    object->error_event = CreateEventW(NULL, TRUE, FALSE, NULL);
     object->init_gst = mpeg_splitter_init_gst;
     *phr = S_OK;
 




More information about the wine-cvs mailing list