From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfsrcsnk/media_source.c | 66 ++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-)
diff --git a/dlls/mfsrcsnk/media_source.c b/dlls/mfsrcsnk/media_source.c index caef4c0d218..5cc769b93b0 100644 --- a/dlls/mfsrcsnk/media_source.c +++ b/dlls/mfsrcsnk/media_source.c @@ -171,6 +171,7 @@ struct media_source IMFAsyncCallback async_create_iface; IMFAsyncCallback async_start_iface; IMFAsyncCallback async_stop_iface; + IMFAsyncCallback async_pause_iface; LONG refcount;
CRITICAL_SECTION cs; @@ -192,6 +193,7 @@ struct media_source enum { SOURCE_STOPPED, + SOURCE_PAUSED, SOURCE_RUNNING, SOURCE_SHUTDOWN, } state; @@ -363,6 +365,51 @@ static HRESULT media_source_async_stop(struct media_source *source, IMFAsyncResu
DEFINE_MF_ASYNC_CALLBACK(media_source, async_stop, IMFMediaSource_iface)
+static void media_stream_pause(struct media_stream *stream) +{ + TRACE("stream %p\n", stream); + + if (stream->active) + queue_media_event_value(stream->queue, MEStreamPaused, NULL); +} + +static HRESULT media_source_pause(struct media_source *source) +{ + unsigned int i; + + TRACE("source %p\n", source); + + if (source->state == SOURCE_SHUTDOWN) + return MF_E_SHUTDOWN; + + for (i = 0; i < source->stream_count; i++) + { + struct media_stream *stream = source->streams[i]; + media_stream_pause(stream); + } + + source->state = SOURCE_PAUSED; + queue_media_event_value(source->queue, MESourcePaused, NULL); + return S_OK; +} + +static HRESULT media_source_async_pause(struct media_source *source, IMFAsyncResult *result) +{ + HRESULT hr; + + EnterCriticalSection(&source->cs); + source->pending_state--; + + if (FAILED(hr = media_source_pause(source))) + WARN("Failed to pause source %p, hr %#lx\n", source, hr); + + LeaveCriticalSection(&source->cs); + + return hr; +} + +DEFINE_MF_ASYNC_CALLBACK(media_source, async_pause, IMFMediaSource_iface) + static struct media_stream *media_stream_from_IMFMediaStream(IMFMediaStream *iface) { return CONTAINING_RECORD(iface, struct media_stream, IMFMediaStream_iface); @@ -946,8 +993,22 @@ static HRESULT WINAPI media_source_Stop(IMFMediaSource *iface) static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface) { struct media_source *source = media_source_from_IMFMediaSource(iface); - FIXME("source %p, stub!\n", source); - return E_NOTIMPL; + HRESULT hr; + + TRACE("source %p\n", source); + + EnterCriticalSection(&source->cs); + + if (source->state == SOURCE_SHUTDOWN) + hr = MF_E_SHUTDOWN; + else if (source->state != SOURCE_RUNNING) + hr = MF_E_INVALID_STATE_TRANSITION; + else if (SUCCEEDED(hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &source->async_pause_iface, NULL))) + source->pending_state++; + + LeaveCriticalSection(&source->cs); + + return hr; }
static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) @@ -1348,6 +1409,7 @@ static HRESULT media_source_create(const WCHAR *url, IMFByteStream *stream, IMFM source->async_create_iface.lpVtbl = &media_source_async_create_vtbl; source->async_start_iface.lpVtbl = &media_source_async_start_vtbl; source->async_stop_iface.lpVtbl = &media_source_async_stop_vtbl; + source->async_pause_iface.lpVtbl = &media_source_async_pause_vtbl; source->refcount = 1;
if (FAILED(hr = MFCreateEventQueue(&source->queue)))