Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/seeking.c | 53 +++++++++++++++++++-------------- dlls/winegstreamer/gstdemux.c | 5 ++-- dlls/wineqtdecoder/qtsplitter.c | 3 +- include/wine/strmbase.h | 7 +++-- 4 files changed, 40 insertions(+), 28 deletions(-)
diff --git a/dlls/strmbase/seeking.c b/dlls/strmbase/seeking.c index 8a773b51d5..d87e4f8516 100644 --- a/dlls/strmbase/seeking.c +++ b/dlls/strmbase/seeking.c @@ -18,7 +18,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* FIXME: critical sections */
#include "strmbase_private.h"
@@ -29,7 +28,9 @@ static inline SourceSeeking *impl_from_IMediaSeeking(IMediaSeeking *iface) return CONTAINING_RECORD(iface, SourceSeeking, IMediaSeeking_iface); }
-HRESULT SourceSeeking_Init(SourceSeeking *pSeeking, const IMediaSeekingVtbl *Vtbl, SourceSeeking_ChangeStop fnChangeStop, SourceSeeking_ChangeStart fnChangeStart, SourceSeeking_ChangeRate fnChangeRate, PCRITICAL_SECTION crit_sect) +HRESULT strmbase_seeking_init(SourceSeeking *pSeeking, const IMediaSeekingVtbl *Vtbl, + SourceSeeking_ChangeStop fnChangeStop, SourceSeeking_ChangeStart fnChangeStart, + SourceSeeking_ChangeRate fnChangeRate) { assert(fnChangeStop && fnChangeStart && fnChangeRate);
@@ -48,10 +49,16 @@ HRESULT SourceSeeking_Init(SourceSeeking *pSeeking, const IMediaSeekingVtbl *Vtb pSeeking->llDuration = pSeeking->llStop; pSeeking->dRate = 1.0; pSeeking->timeformat = TIME_FORMAT_MEDIA_TIME; - pSeeking->crst = crit_sect; + InitializeCriticalSection(&pSeeking->cs); + pSeeking->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SourceSeeking.cs"); return S_OK; }
+void strmbase_seeking_cleanup(SourceSeeking *seeking) +{ + DeleteCriticalSection(&seeking->cs); +} + HRESULT WINAPI SourceSeekingImpl_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities) { SourceSeeking *This = impl_from_IMediaSeeking(iface); @@ -104,9 +111,9 @@ HRESULT WINAPI SourceSeekingImpl_GetTimeFormat(IMediaSeeking * iface, GUID * pFo SourceSeeking *This = impl_from_IMediaSeeking(iface); TRACE("(%s)\n", debugstr_guid(pFormat));
- EnterCriticalSection(This->crst); + EnterCriticalSection(&This->cs); *pFormat = This->timeformat; - LeaveCriticalSection(This->crst); + LeaveCriticalSection(&This->cs);
return S_OK; } @@ -118,10 +125,10 @@ HRESULT WINAPI SourceSeekingImpl_IsUsingTimeFormat(IMediaSeeking * iface, const
TRACE("(%s)\n", debugstr_guid(pFormat));
- EnterCriticalSection(This->crst); + EnterCriticalSection(&This->cs); if (!IsEqualIID(pFormat, &This->timeformat)) hr = S_FALSE; - LeaveCriticalSection(This->crst); + LeaveCriticalSection(&This->cs);
return hr; } @@ -140,9 +147,9 @@ HRESULT WINAPI SourceSeekingImpl_GetDuration(IMediaSeeking * iface, LONGLONG * p
TRACE("(%p)\n", pDuration);
- EnterCriticalSection(This->crst); + EnterCriticalSection(&This->cs); *pDuration = This->llDuration; - LeaveCriticalSection(This->crst); + LeaveCriticalSection(&This->cs);
return S_OK; } @@ -153,9 +160,9 @@ HRESULT WINAPI SourceSeekingImpl_GetStopPosition(IMediaSeeking * iface, LONGLONG
TRACE("(%p)\n", pStop);
- EnterCriticalSection(This->crst); + EnterCriticalSection(&This->cs); *pStop = This->llStop; - LeaveCriticalSection(This->crst); + LeaveCriticalSection(&This->cs);
return S_OK; } @@ -167,9 +174,9 @@ HRESULT WINAPI SourceSeekingImpl_GetCurrentPosition(IMediaSeeking * iface, LONGL
TRACE("(%p)\n", pCurrent);
- EnterCriticalSection(This->crst); + EnterCriticalSection(&This->cs); *pCurrent = This->llCurrent; - LeaveCriticalSection(This->crst); + LeaveCriticalSection(&This->cs);
return S_OK; } @@ -214,7 +221,7 @@ HRESULT WINAPI SourceSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * LONGLONG llNewCurrent, llNewStop;
TRACE("(%p, %x, %p, %x)\n", pCurrent, dwCurrentFlags, pStop, dwStopFlags); - EnterCriticalSection(This->crst); + EnterCriticalSection(&This->cs);
llNewCurrent = Adjust(This->llCurrent, pCurrent, dwCurrentFlags); llNewStop = Adjust(This->llStop, pStop, dwStopFlags); @@ -233,7 +240,7 @@ HRESULT WINAPI SourceSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * *pCurrent = llNewCurrent; if (pStop && (dwStopFlags & AM_SEEKING_ReturnTime)) *pStop = llNewStop; - LeaveCriticalSection(This->crst); + LeaveCriticalSection(&This->cs);
if (bChangeCurrent) This->fnChangeStart(iface); @@ -249,10 +256,10 @@ HRESULT WINAPI SourceSeekingImpl_GetPositions(IMediaSeeking * iface, LONGLONG *
TRACE("(%p, %p)\n", pCurrent, pStop);
- EnterCriticalSection(This->crst); + EnterCriticalSection(&This->cs); IMediaSeeking_GetCurrentPosition(iface, pCurrent); IMediaSeeking_GetStopPosition(iface, pStop); - LeaveCriticalSection(This->crst); + LeaveCriticalSection(&This->cs);
return S_OK; } @@ -263,10 +270,10 @@ HRESULT WINAPI SourceSeekingImpl_GetAvailable(IMediaSeeking * iface, LONGLONG *
TRACE("(%p, %p)\n", pEarliest, pLatest);
- EnterCriticalSection(This->crst); + EnterCriticalSection(&This->cs); *pEarliest = 0; *pLatest = This->llDuration; - LeaveCriticalSection(This->crst); + LeaveCriticalSection(&This->cs);
return S_OK; } @@ -285,11 +292,11 @@ HRESULT WINAPI SourceSeekingImpl_SetRate(IMediaSeeking * iface, double dRate) return VFW_E_UNSUPPORTED_AUDIO; }
- EnterCriticalSection(This->crst); + EnterCriticalSection(&This->cs); This->dRate = dRate; if (bChangeRate) hr = This->fnChangeRate(iface); - LeaveCriticalSection(This->crst); + LeaveCriticalSection(&This->cs);
return hr; } @@ -300,10 +307,10 @@ HRESULT WINAPI SourceSeekingImpl_GetRate(IMediaSeeking * iface, double * dRate)
TRACE("(%p)\n", dRate);
- EnterCriticalSection(This->crst); + EnterCriticalSection(&This->cs); /* Forward? */ *dRate = This->dRate; - LeaveCriticalSection(This->crst); + LeaveCriticalSection(&This->cs);
return S_OK; } diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 479077b48f..5fa9d66c93 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -1884,6 +1884,7 @@ static void free_source_pin(struct gstdemux_source *pin) FreeMediaType(&pin->mt); gst_segment_free(pin->segment);
+ strmbase_seeking_cleanup(&pin->seek); strmbase_source_cleanup(&pin->pin); heap_free(pin); } @@ -1936,8 +1937,8 @@ static struct gstdemux_source *create_pin(struct gstdemux *filter, const WCHAR * pin->segment = gst_segment_new(); gst_segment_init(pin->segment, GST_FORMAT_TIME); pin->IQualityControl_iface.lpVtbl = &GSTOutPin_QualityControl_Vtbl; - SourceSeeking_Init(&pin->seek, &GST_Seeking_Vtbl, GST_ChangeStop, - GST_ChangeCurrent, GST_ChangeRate, &filter->filter.csFilter); + strmbase_seeking_init(&pin->seek, &GST_Seeking_Vtbl, GST_ChangeStop, + GST_ChangeCurrent, GST_ChangeRate); BaseFilterImpl_IncrementPinVersion(&filter->filter);
sprintf(pad_name, "qz_sink_%u", filter->cStreams); diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c index fbec10a912..81e18d3420 100644 --- a/dlls/wineqtdecoder/qtsplitter.c +++ b/dlls/wineqtdecoder/qtsplitter.c @@ -340,7 +340,8 @@ IUnknown * CALLBACK QTSplitter_create(IUnknown *outer, HRESULT *phr) This->pInputPin.pin.peer = NULL; This->pInputPin.pin.pFuncsTable = &sink_ops;
- SourceSeeking_Init(&This->sourceSeeking, &QT_Seeking_Vtbl, QTSplitter_ChangeStop, QTSplitter_ChangeStart, QTSplitter_ChangeRate, &This->filter.csFilter); + strmbase_seeking_init(&This->sourceSeeking, &QT_Seeking_Vtbl, + QTSplitter_ChangeStop, QTSplitter_ChangeStart, QTSplitter_ChangeRate);
*phr = S_OK; return &This->filter.IUnknown_inner; diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index b08303f93d..7949e6670a 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -272,10 +272,13 @@ typedef struct SourceSeeking double dRate; LONGLONG llCurrent, llStop, llDuration; GUID timeformat; - PCRITICAL_SECTION crst; + CRITICAL_SECTION cs; } SourceSeeking;
-HRESULT SourceSeeking_Init(SourceSeeking *pSeeking, const IMediaSeekingVtbl *Vtbl, SourceSeeking_ChangeStop fnChangeStop, SourceSeeking_ChangeStart fnChangeStart, SourceSeeking_ChangeRate fnChangeRate, PCRITICAL_SECTION crit_sect); +HRESULT strmbase_seeking_init(SourceSeeking *seeking, const IMediaSeekingVtbl *vtbl, + SourceSeeking_ChangeStop fnChangeStop, SourceSeeking_ChangeStart fnChangeStart, + SourceSeeking_ChangeRate fnChangeRate); +void strmbase_seeking_cleanup(SourceSeeking *seeking);
HRESULT WINAPI SourceSeekingImpl_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities); HRESULT WINAPI SourceSeekingImpl_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities);
This may be called from the streaming thread, so it's not safe to do so.
Nor does it seem necessary. We expect that no streaming thread should ever call methods on our pad or pin, and as long as we hold the filter lock and wait for the no-more-pads signal when connecting or starting the stream, we cannot race with application threads.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 5fa9d66c93..f5be9f6c10 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -971,7 +971,6 @@ static void existing_new_pad(GstElement *bin, GstPad *pad, gpointer user) return; }
- EnterCriticalSection(&This->filter.csFilter); for (x = 0; x < This->cStreams; ++x) { struct gstdemux_source *pin = This->ppPins[x]; if (!pin->their_src) { @@ -986,13 +985,11 @@ static void existing_new_pad(GstElement *bin, GstPad *pad, gpointer user) pin->their_src = pad; gst_object_ref(pin->their_src); TRACE("Relinked\n"); - LeaveCriticalSection(&This->filter.csFilter); return; } } } init_new_decoded_pad(bin, pad, This); - LeaveCriticalSection(&This->filter.csFilter); }
static gboolean query_function(GstPad *pad, GstObject *parent, GstQuery *query)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index f5be9f6c10..93d63106f7 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -1430,8 +1430,17 @@ static HRESULT WINAPI GST_Run(IBaseFilter *iface, REFERENCE_TIME tStart) }
EnterCriticalSection(&This->filter.csFilter); + + if (This->no_more_pads_event) + ResetEvent(This->no_more_pads_event); + gst_element_set_state(This->container, GST_STATE_PLAYING);
+ /* Make sure that all of our pads are connected before returning, lest we + * e.g. try to seek and fail. */ + if (This->no_more_pads_event) + WaitForSingleObject(This->no_more_pads_event, INFINITE); + for (i = 0; i < This->cStreams; i++) { hr = BaseOutputPinImpl_Active(&This->ppPins[i]->pin); if (SUCCEEDED(hr)) {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 255 ++++++++++++++++------------------ 1 file changed, 122 insertions(+), 133 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 93d63106f7..a00480c318 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -88,11 +88,6 @@ struct gstdemux_source SourceSeeking seek; };
-static inline struct gstdemux *impl_from_IBaseFilter(IBaseFilter *iface) -{ - return CONTAINING_RECORD(iface, struct gstdemux, filter.IBaseFilter_iface); -} - static inline struct gstdemux *impl_from_strmbase_filter(struct strmbase_filter *iface) { return CONTAINING_RECORD(iface, struct gstdemux, filter); @@ -1246,10 +1241,123 @@ static void gstdemux_destroy(struct strmbase_filter *iface) heap_free(filter); }
+static HRESULT gstdemux_init_stream(struct strmbase_filter *iface) +{ + struct gstdemux *filter = impl_from_strmbase_filter(iface); + HRESULT hr = VFW_E_NOT_CONNECTED, pin_hr; + GstStateChangeReturn ret; + unsigned int i; + + if (!filter->container) + return VFW_E_NOT_CONNECTED; + + if (filter->no_more_pads_event) + ResetEvent(filter->no_more_pads_event); + + if ((ret = gst_element_set_state(filter->container, GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE) + { + ERR("Failed to pause stream.\n"); + return E_FAIL; + } + + /* Make sure that all of our pads are connected before returning, lest we + * e.g. try to seek and fail. */ + if (filter->no_more_pads_event) + WaitForSingleObject(filter->no_more_pads_event, INFINITE); + + for (i = 0; i < filter->cStreams; ++i) + { + if (SUCCEEDED(pin_hr = BaseOutputPinImpl_Active(&filter->ppPins[i]->pin))) + hr = pin_hr; + } + return hr; +} + +static HRESULT gstdemux_start_stream(struct strmbase_filter *iface, REFERENCE_TIME time) +{ + struct gstdemux *filter = impl_from_strmbase_filter(iface); + GstStateChangeReturn ret; + + if (!filter->container) + return VFW_E_NOT_CONNECTED; + + if ((ret = gst_element_set_state(filter->container, GST_STATE_PLAYING)) == GST_STATE_CHANGE_FAILURE) + { + ERR("Failed to play stream.\n"); + return E_FAIL; + } + else if (ret == GST_STATE_CHANGE_ASYNC) + return S_FALSE; + return S_OK; +} + +static HRESULT gstdemux_stop_stream(struct strmbase_filter *iface) +{ + struct gstdemux *filter = impl_from_strmbase_filter(iface); + GstStateChangeReturn ret; + + if (!filter->container) + return VFW_E_NOT_CONNECTED; + + if ((ret = gst_element_set_state(filter->container, GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE) + { + ERR("Failed to pause stream.\n"); + return E_FAIL; + } + else if (ret == GST_STATE_CHANGE_ASYNC) + return S_FALSE; + return S_OK; +} + +static HRESULT gstdemux_cleanup_stream(struct strmbase_filter *iface) +{ + struct gstdemux *filter = impl_from_strmbase_filter(iface); + GstStateChangeReturn ret; + + if (!filter->container) + return S_OK; + + filter->ignore_flush = TRUE; + if ((ret = gst_element_set_state(filter->container, GST_STATE_READY)) == GST_STATE_CHANGE_FAILURE) + { + ERR("Failed to pause stream.\n"); + return E_FAIL; + } + gst_element_get_state(filter->container, NULL, NULL, GST_CLOCK_TIME_NONE); + filter->ignore_flush = FALSE; + + return S_OK; +} + +static HRESULT gstdemux_wait_state(struct strmbase_filter *iface, DWORD timeout) +{ + struct gstdemux *filter = impl_from_strmbase_filter(iface); + GstStateChangeReturn ret; + + if (!filter->container) + return S_OK; + + ret = gst_element_get_state(filter->container, NULL, NULL, + timeout == INFINITE ? GST_CLOCK_TIME_NONE : timeout * 1000); + if (ret == GST_STATE_CHANGE_FAILURE) + { + ERR("Failed to get state.\n"); + return E_FAIL; + } + else if (ret == GST_STATE_CHANGE_ASYNC) + return VFW_S_STATE_INTERMEDIATE; + return S_OK; +} + static const struct strmbase_filter_ops filter_ops = { .filter_get_pin = gstdemux_get_pin, .filter_destroy = gstdemux_destroy, + .filter_init_stream = gstdemux_init_stream, + .filter_start_stream = gstdemux_start_stream, + .filter_stop_stream = gstdemux_stop_stream, + .filter_cleanup_stream = gstdemux_cleanup_stream, + .filter_wait_state = gstdemux_wait_state, };
static HRESULT sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt) @@ -1359,139 +1467,15 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr) return &object->filter.IUnknown_inner; }
-static HRESULT WINAPI GST_Stop(IBaseFilter *iface) -{ - struct gstdemux *This = impl_from_IBaseFilter(iface); - - TRACE("(%p)\n", This); - - mark_wine_thread(); - - if (This->container) { - This->ignore_flush = TRUE; - gst_element_set_state(This->container, GST_STATE_READY); - gst_element_get_state(This->container, NULL, NULL, -1); - This->ignore_flush = FALSE; - } - return S_OK; -} - -static HRESULT WINAPI GST_Pause(IBaseFilter *iface) -{ - struct gstdemux *This = impl_from_IBaseFilter(iface); - HRESULT hr = S_OK; - GstState now; - GstStateChangeReturn ret; - - TRACE("(%p)\n", This); - - if (!This->container) - return VFW_E_NOT_CONNECTED; - - mark_wine_thread(); - - gst_element_get_state(This->container, &now, NULL, -1); - if (now == GST_STATE_PAUSED) - return S_OK; - if (now != GST_STATE_PLAYING) - hr = IBaseFilter_Run(iface, -1); - if (FAILED(hr)) - return hr; - ret = gst_element_set_state(This->container, GST_STATE_PAUSED); - if (ret == GST_STATE_CHANGE_ASYNC) - hr = S_FALSE; - return hr; -} - -static HRESULT WINAPI GST_Run(IBaseFilter *iface, REFERENCE_TIME tStart) -{ - struct gstdemux *This = impl_from_IBaseFilter(iface); - HRESULT hr = S_OK; - ULONG i; - GstState now; - HRESULT hr_any = VFW_E_NOT_CONNECTED; - - TRACE("(%p)->(%s)\n", This, wine_dbgstr_longlong(tStart)); - - mark_wine_thread(); - - if (!This->container) - return VFW_E_NOT_CONNECTED; - - gst_element_get_state(This->container, &now, NULL, -1); - if (now == GST_STATE_PLAYING) - return S_OK; - if (now == GST_STATE_PAUSED) { - GstStateChangeReturn ret; - ret = gst_element_set_state(This->container, GST_STATE_PLAYING); - if (ret == GST_STATE_CHANGE_ASYNC) - return S_FALSE; - return S_OK; - } - - EnterCriticalSection(&This->filter.csFilter); - - if (This->no_more_pads_event) - ResetEvent(This->no_more_pads_event); - - gst_element_set_state(This->container, GST_STATE_PLAYING); - - /* Make sure that all of our pads are connected before returning, lest we - * e.g. try to seek and fail. */ - if (This->no_more_pads_event) - WaitForSingleObject(This->no_more_pads_event, INFINITE); - - for (i = 0; i < This->cStreams; i++) { - hr = BaseOutputPinImpl_Active(&This->ppPins[i]->pin); - if (SUCCEEDED(hr)) { - hr_any = hr; - } - } - hr = hr_any; - LeaveCriticalSection(&This->filter.csFilter); - - return hr; -} - -static HRESULT WINAPI GST_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) -{ - struct gstdemux *This = impl_from_IBaseFilter(iface); - HRESULT hr = S_OK; - GstState now, pending; - GstStateChangeReturn ret; - - TRACE("(%p)->(%d, %p)\n", This, dwMilliSecsTimeout, pState); - - mark_wine_thread(); - - if (!This->container) { - *pState = State_Stopped; - return S_OK; - } - - ret = gst_element_get_state(This->container, &now, &pending, dwMilliSecsTimeout == INFINITE ? -1 : dwMilliSecsTimeout * 1000); - - if (ret == GST_STATE_CHANGE_ASYNC) - hr = VFW_S_STATE_INTERMEDIATE; - else - pending = now; - - switch (pending) { - case GST_STATE_PAUSED: *pState = State_Paused; return hr; - case GST_STATE_PLAYING: *pState = State_Running; return hr; - default: *pState = State_Stopped; return hr; - } -} - static const IBaseFilterVtbl GST_Vtbl = { BaseFilterImpl_QueryInterface, BaseFilterImpl_AddRef, BaseFilterImpl_Release, BaseFilterImpl_GetClassID, - GST_Stop, - GST_Pause, - GST_Run, - GST_GetState, + BaseFilterImpl_Stop, + BaseFilterImpl_Pause, + BaseFilterImpl_Run, + BaseFilterImpl_GetState, BaseFilterImpl_SetSyncSource, BaseFilterImpl_GetSyncSource, BaseFilterImpl_EnumPins, @@ -2631,6 +2615,11 @@ static const struct strmbase_filter_ops mpeg_splitter_ops = .filter_query_interface = mpeg_splitter_query_interface, .filter_get_pin = gstdemux_get_pin, .filter_destroy = gstdemux_destroy, + .filter_init_stream = gstdemux_init_stream, + .filter_start_stream = gstdemux_start_stream, + .filter_stop_stream = gstdemux_stop_stream, + .filter_cleanup_stream = gstdemux_cleanup_stream, + .filter_wait_state = gstdemux_wait_state, };
IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr)
Zebediah Figura z.figura12@gmail.com writes:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
dlls/winegstreamer/gstdemux.c | 255 ++++++++++++++++------------------ 1 file changed, 122 insertions(+), 133 deletions(-)
This is still causing deadlocks:
../../../tools/runtest -q -P wine -T ../../.. -M winmm.dll -p winmm_test.exe mci && touch mci.ok 00e2:fixme:mci:MCI_SendCommand unhandled MCI_ALL_DEVICE_ID 00e2:fixme:mci:MCI_SysInfo Don't know how to get # of MCI devices of a given type 00e2:fixme:mci:MCI_SendCommand unhandled MCI_ALL_DEVICE_ID 00e2:fixme:mci:MCI_LoadMciDriver Couldn't load driver for type L"". 00e2:fixme:mci:MCI_LoadMciDriver Couldn't load driver for type L"". 00e2:fixme:mci:MCI_LoadMciDriver Couldn't load driver for type L"NOSUCHDEVICE". 00e2:fixme:mciwave:MCIWAVE_DriverProc Unsupported command [2134] 00e2:fixme:mci:mciSendStringW leaking auto-open device 1 ALSA lib conf.c:3558:(snd_config_hooks_call) Cannot open shared library libasound_module_conf_pulse.so (/usr/lib/i386-linux-gnu/alsa-lib/libasound_module_conf_pulse.so: libasound_module_conf_pulse.so: cannot open shared object file: No such file or directory) ALSA lib seq.c:935:(snd_seq_open_noupdate) Unknown SEQ default 00e2:err:winediag:MIDIMAP_drvOpen No software synthesizer midi port found, Midi sound output probably won't work. 00e2:fixme:gstreamer:source_query_accept (0x6ea688) stub 00f9:err:ntdll:RtlpWaitForCriticalSection section 0x6ea1f0 "../strmbase/filter.c: strmbase_filter.csFilter" wait timed out in thread 00f9, blocked by 00fb, retrying (60 sec)
On 12/3/19 2:38 AM, Alexandre Julliard wrote:
Zebediah Figura z.figura12@gmail.com writes:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
dlls/winegstreamer/gstdemux.c | 255 ++++++++++++++++------------------ 1 file changed, 122 insertions(+), 133 deletions(-)
This is still causing deadlocks:
../../../tools/runtest -q -P wine -T ../../.. -M winmm.dll -p winmm_test.exe mci && touch mci.ok 00e2:fixme:mci:MCI_SendCommand unhandled MCI_ALL_DEVICE_ID 00e2:fixme:mci:MCI_SysInfo Don't know how to get # of MCI devices of a given type 00e2:fixme:mci:MCI_SendCommand unhandled MCI_ALL_DEVICE_ID 00e2:fixme:mci:MCI_LoadMciDriver Couldn't load driver for type L"". 00e2:fixme:mci:MCI_LoadMciDriver Couldn't load driver for type L"". 00e2:fixme:mci:MCI_LoadMciDriver Couldn't load driver for type L"NOSUCHDEVICE". 00e2:fixme:mciwave:MCIWAVE_DriverProc Unsupported command [2134] 00e2:fixme:mci:mciSendStringW leaking auto-open device 1 ALSA lib conf.c:3558:(snd_config_hooks_call) Cannot open shared library libasound_module_conf_pulse.so (/usr/lib/i386-linux-gnu/alsa-lib/libasound_module_conf_pulse.so: libasound_module_conf_pulse.so: cannot open shared object file: No such file or directory) ALSA lib seq.c:935:(snd_seq_open_noupdate) Unknown SEQ default 00e2:err:winediag:MIDIMAP_drvOpen No software synthesizer midi port found, Midi sound output probably won't work. 00e2:fixme:gstreamer:source_query_accept (0x6ea688) stub 00f9:err:ntdll:RtlpWaitForCriticalSection section 0x6ea1f0 "../strmbase/filter.c: strmbase_filter.csFilter" wait timed out in thread 00f9, blocked by 00fb, retrying (60 sec)
Thanks, it seems I misread the gstreamer code and mistakenly judged that pad-removed was not sent from the streaming thread. I'll send a new patch set that addresses this.