From: Anton Baskanov baskanov@gmail.com
Signed-off-by: Anton Baskanov baskanov@gmail.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: no changes.
dlls/amstream/multimedia.c | 51 +++++++++++++++++++++++++++------- dlls/amstream/tests/amstream.c | 12 ++++---- 2 files changed, 47 insertions(+), 16 deletions(-)
diff --git a/dlls/amstream/multimedia.c b/dlls/amstream/multimedia.c index 07c037505e1..be8fd4ecbfc 100644 --- a/dlls/amstream/multimedia.c +++ b/dlls/amstream/multimedia.c @@ -298,6 +298,16 @@ static HRESULT WINAPI multimedia_stream_GetFilter(IAMMultiMediaStream *iface, return S_OK; }
+static void add_stream(struct multimedia_stream *mmstream, IAMMediaStream *stream, IMediaStream **ret_stream) +{ + IMediaStreamFilter_AddMediaStream(mmstream->filter, stream); + if (ret_stream) + { + *ret_stream = (IMediaStream *)stream; + IMediaStream_AddRef(*ret_stream); + } +} + static HRESULT WINAPI multimedia_stream_AddMediaStream(IAMMultiMediaStream *iface, IUnknown *stream_object, const MSPID *PurposeId, DWORD dwFlags, IMediaStream **ret_stream) { @@ -309,9 +319,6 @@ static HRESULT WINAPI multimedia_stream_AddMediaStream(IAMMultiMediaStream *ifac TRACE("mmstream %p, stream_object %p, id %s, flags %#x, ret_stream %p.\n", This, stream_object, debugstr_guid(PurposeId), dwFlags, ret_stream);
- if (!IsEqualGUID(PurposeId, &MSPID_PrimaryVideo) && !IsEqualGUID(PurposeId, &MSPID_PrimaryAudio)) - return MS_E_PURPOSEID; - if (IMediaStreamFilter_GetMediaStream(This->filter, PurposeId, &stream) == S_OK) { IMediaStream_Release(stream); @@ -343,19 +350,43 @@ static HRESULT WINAPI multimedia_stream_AddMediaStream(IAMMultiMediaStream *ifac return hr; }
+ if (stream_object) + { + hr = IUnknown_QueryInterface(stream_object, &IID_IAMMediaStream, (void **)&pStream); + if (SUCCEEDED(hr)) + { + MSPID stream_id; + hr = IAMMediaStream_GetInformation(pStream, &stream_id, NULL); + if (SUCCEEDED(hr)) + { + if (IsEqualGUID(PurposeId, &stream_id)) + { + add_stream(This, pStream, ret_stream); + hr = S_OK; + } + else + { + hr = MS_E_PURPOSEID; + } + } + + IAMMediaStream_Release(pStream); + + return hr; + } + } + if (IsEqualGUID(PurposeId, &MSPID_PrimaryVideo)) hr = ddraw_stream_create((IMultiMediaStream*)iface, PurposeId, stream_object, This->type, &pStream); - else + else if (IsEqualGUID(PurposeId, &MSPID_PrimaryAudio)) hr = audio_stream_create((IMultiMediaStream*)iface, PurposeId, stream_object, This->type, &pStream); + else + return MS_E_PURPOSEID;
if (SUCCEEDED(hr)) { - /* Add stream to the media stream filter */ - IMediaStreamFilter_AddMediaStream(This->filter, pStream); - if (ret_stream) - *ret_stream = (IMediaStream *)pStream; - else - IAMMediaStream_Release(pStream); + add_stream(This, pStream, ret_stream); + IAMMediaStream_Release(pStream); }
return hr; diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index a55884d8abf..09686cfcf4d 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -684,21 +684,21 @@ static void test_add_stream(void) ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream, &test_mspid, 0, &stream); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(stream == (IMediaStream *)&teststream, "Streams didn't match.\n"); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(stream == (IMediaStream *)&teststream, "Streams didn't match.\n"); if (hr == S_OK) IMediaStream_Release(stream); todo_wine ok(teststream_mmstream == mmstream, "IAMMultiMediaStream objects didn't match.\n"); - todo_wine ok(teststream_filter == stream_filter, "IMediaStreamFilter objects didn't match.\n"); + ok(teststream_filter == stream_filter, "IMediaStreamFilter objects didn't match.\n"); todo_wine ok(!!teststream_graph, "Expected a non-NULL graph.\n");
check_enum_stream(mmstream, stream_filter, 0, video_stream); check_enum_stream(mmstream, stream_filter, 1, audio_stream); - todo_wine check_enum_stream(mmstream, stream_filter, 2, (IMediaStream *)&teststream); + check_enum_stream(mmstream, stream_filter, 2, (IMediaStream *)&teststream); check_enum_stream(mmstream, stream_filter, 3, NULL);
check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, video_stream); check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, audio_stream); - todo_wine check_get_stream(mmstream, stream_filter, &test_mspid, (IMediaStream *)&teststream); + check_get_stream(mmstream, stream_filter, &test_mspid, (IMediaStream *)&teststream);
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream); ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr); @@ -839,7 +839,7 @@ static void test_add_stream(void) ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr); hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &test_mspid, AMMSF_ADDDEFAULTRENDERER, &audio_stream); - todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
IMediaStreamFilter_Release(stream_filter); ref = IAMMultiMediaStream_Release(mmstream);
From: Anton Baskanov baskanov@gmail.com
Signed-off-by: Anton Baskanov baskanov@gmail.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: punctuate a couple of messages.
dlls/amstream/filter.c | 15 +++++++++++++-- dlls/amstream/tests/amstream.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/dlls/amstream/filter.c b/dlls/amstream/filter.c index 80a885de244..1cb2ca71bac 100644 --- a/dlls/amstream/filter.c +++ b/dlls/amstream/filter.c @@ -171,6 +171,7 @@ struct filter IFilterGraph *graph; ULONG nb_streams; IAMMediaStream **streams; + FILTER_STATE state; };
static inline struct filter *impl_from_IMediaStreamFilter(IMediaStreamFilter *iface) @@ -264,9 +265,19 @@ static HRESULT WINAPI filter_Run(IMediaStreamFilter *iface, REFERENCE_TIME start
static HRESULT WINAPI filter_GetState(IMediaStreamFilter *iface, DWORD timeout, FILTER_STATE *state) { - FIXME("iface %p, timeout %u, state %p, stub!\n", iface, timeout, state); + struct filter *filter = impl_from_IMediaStreamFilter(iface); + + TRACE("iface %p, timeout %u, state %p.\n", iface, timeout, state); + + if (!state) + return E_POINTER; + + EnterCriticalSection(&filter->cs); + + *state = filter->state; + + LeaveCriticalSection(&filter->cs);
- *state = State_Stopped; return S_OK; }
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 09686cfcf4d..cfdd8b6c8d4 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -2737,6 +2737,37 @@ static void test_audiostream_receive_connection(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+void test_mediastreamfilter_get_state(void) +{ + IAMMultiMediaStream *mmstream = create_ammultimediastream(); + IMediaStreamFilter *filter; + FILTER_STATE state; + HRESULT hr; + ULONG ref; + + hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IAMMultiMediaStream_GetFilter(mmstream, &filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!filter, "Expected non-null filter.\n"); + + /* Crashes on native. */ + if (0) + { + hr = IMediaStreamFilter_GetState(filter, 0, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + } + + state = 0xcc; + hr = IMediaStreamFilter_GetState(filter, 0, &state); + ok(state == State_Stopped, "Got state %#x.\n", state); + + ref = IAMMultiMediaStream_Release(mmstream); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IMediaStreamFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + START_TEST(amstream) { HANDLE file; @@ -2774,5 +2805,7 @@ START_TEST(amstream) test_audiostream_set_format(); test_audiostream_receive_connection();
+ test_mediastreamfilter_get_state(); + CoUninitialize(); }
From: Anton Baskanov baskanov@gmail.com
Signed-off-by: Anton Baskanov baskanov@gmail.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: rename teststream_from_*() helpers to impl_from_*(), to match usual COM helper naming.
dlls/amstream/tests/amstream.c | 74 ++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 21 deletions(-)
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index cfdd8b6c8d4..02fea447d0c 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -305,25 +305,43 @@ error: }
static const GUID test_mspid = {0x88888888}; -static IAMMediaStream teststream; -static LONG teststream_refcount = 1; -static IAMMultiMediaStream *teststream_mmstream; -static IMediaStreamFilter *teststream_filter; -static IFilterGraph *teststream_graph; + +struct teststream +{ + IAMMediaStream IAMMediaStream_iface; + IPin IPin_iface; + LONG refcount; + IAMMultiMediaStream *mmstream; + IMediaStreamFilter *filter; + IFilterGraph *graph; +}; + +static struct teststream *impl_from_IAMMediaStream(IAMMediaStream *iface) +{ + return CONTAINING_RECORD(iface, struct teststream, IAMMediaStream_iface); +} + +static struct teststream *impl_from_IPin(IPin *iface) +{ + return CONTAINING_RECORD(iface, struct teststream, IPin_iface); +}
static HRESULT WINAPI pin_QueryInterface(IPin *iface, REFIID iid, void **out) { - return IAMMediaStream_QueryInterface(&teststream, iid, out); + struct teststream *stream = impl_from_IPin(iface); + return IAMMediaStream_QueryInterface(&stream->IAMMediaStream_iface, iid, out); }
static ULONG WINAPI pin_AddRef(IPin *iface) { - return IAMMediaStream_AddRef(&teststream); + struct teststream *stream = impl_from_IPin(iface); + return IAMMediaStream_AddRef(&stream->IAMMediaStream_iface); }
static ULONG WINAPI pin_Release(IPin *iface) { - return IAMMediaStream_Release(&teststream); + struct teststream *stream = impl_from_IPin(iface); + return IAMMediaStream_Release(&stream->IAMMediaStream_iface); }
static HRESULT WINAPI pin_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) @@ -439,10 +457,10 @@ static const IPinVtbl pin_vtbl = pin_NewSegment };
-static IPin testpin = {&pin_vtbl}; - static HRESULT WINAPI stream_QueryInterface(IAMMediaStream *iface, REFIID iid, void **out) { + struct teststream *stream = impl_from_IAMMediaStream(iface); + if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IMediaStream) || IsEqualGUID(iid, &IID_IAMMediaStream)) @@ -454,7 +472,7 @@ static HRESULT WINAPI stream_QueryInterface(IAMMediaStream *iface, REFIID iid, v else if (IsEqualGUID(iid, &IID_IPin)) { IAMMediaStream_AddRef(iface); - *out = &testpin; + *out = &stream->IPin_iface; return S_OK; }
@@ -464,12 +482,14 @@ static HRESULT WINAPI stream_QueryInterface(IAMMediaStream *iface, REFIID iid, v
static ULONG WINAPI stream_AddRef(IAMMediaStream *iface) { - return InterlockedIncrement(&teststream_refcount); + struct teststream *stream = impl_from_IAMMediaStream(iface); + return InterlockedIncrement(&stream->refcount); }
static ULONG WINAPI stream_Release(IAMMediaStream *iface) { - return InterlockedDecrement(&teststream_refcount); + struct teststream *stream = impl_from_IAMMediaStream(iface); + return InterlockedDecrement(&stream->refcount); }
static HRESULT WINAPI stream_GetMultiMediaStream(IAMMediaStream *iface, IMultiMediaStream **mmstream) @@ -526,22 +546,25 @@ static HRESULT WINAPI stream_SetState(IAMMediaStream *iface, FILTER_STATE state)
static HRESULT WINAPI stream_JoinAMMultiMediaStream(IAMMediaStream *iface, IAMMultiMediaStream *mmstream) { + struct teststream *stream = impl_from_IAMMediaStream(iface); if (winetest_debug > 1) trace("JoinAMMultiMediaStream(%p)\n", mmstream); - teststream_mmstream = mmstream; + stream->mmstream = mmstream; return S_OK; }
static HRESULT WINAPI stream_JoinFilter(IAMMediaStream *iface, IMediaStreamFilter *filter) { + struct teststream *stream = impl_from_IAMMediaStream(iface); if (winetest_debug > 1) trace("JoinFilter(%p)\n", filter); - teststream_filter = filter; + stream->filter = filter; return S_OK; }
static HRESULT WINAPI stream_JoinFilterGraph(IAMMediaStream *iface, IFilterGraph *graph) { + struct teststream *stream = impl_from_IAMMediaStream(iface); if (winetest_debug > 1) trace("JoinFilterGraph(%p)\n", graph); - teststream_graph = graph; + stream->graph = graph; return S_OK; }
@@ -563,7 +586,13 @@ static const IAMMediaStreamVtbl stream_vtbl = stream_JoinFilterGraph, };
-static IAMMediaStream teststream = {&stream_vtbl}; +static void teststream_init(struct teststream *stream) +{ + memset(stream, 0, sizeof(*stream)); + stream->IAMMediaStream_iface.lpVtbl = &stream_vtbl; + stream->IPin_iface.lpVtbl = &pin_vtbl; + stream->refcount = 1; +}
#define check_enum_stream(a,b,c,d) check_enum_stream_(__LINE__,a,b,c,d) static void check_enum_stream_(int line, IAMMultiMediaStream *mmstream, @@ -616,6 +645,7 @@ static void test_add_stream(void) IMediaStream *video_stream, *audio_stream, *stream; IDirectDrawMediaStream *ddraw_stream; IMediaStreamFilter *stream_filter; + struct teststream teststream; IDirectDraw *ddraw, *ddraw2; IEnumFilters *enum_filters; IBaseFilter *filters[3]; @@ -624,6 +654,8 @@ static void test_add_stream(void) CLSID clsid; HRESULT hr;
+ teststream_init(&teststream); + hr = IAMMultiMediaStream_GetFilter(mmstream, &stream_filter); ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -687,9 +719,9 @@ static void test_add_stream(void) ok(hr == S_OK, "Got hr %#x.\n", hr); ok(stream == (IMediaStream *)&teststream, "Streams didn't match.\n"); if (hr == S_OK) IMediaStream_Release(stream); - todo_wine ok(teststream_mmstream == mmstream, "IAMMultiMediaStream objects didn't match.\n"); - ok(teststream_filter == stream_filter, "IMediaStreamFilter objects didn't match.\n"); - todo_wine ok(!!teststream_graph, "Expected a non-NULL graph.\n"); + todo_wine ok(teststream.mmstream == mmstream, "IAMMultiMediaStream objects didn't match.\n"); + ok(teststream.filter == stream_filter, "IMediaStreamFilter objects didn't match.\n"); + todo_wine ok(!!teststream.graph, "Expected a non-NULL graph.\n");
check_enum_stream(mmstream, stream_filter, 0, video_stream); check_enum_stream(mmstream, stream_filter, 1, audio_stream); @@ -725,7 +757,7 @@ static void test_add_stream(void) ok(!ref, "Got outstanding refcount %d.\n", ref); ref = IMediaStream_Release(audio_stream); ok(!ref, "Got outstanding refcount %d.\n", ref); - ok(teststream_refcount == 1, "Got outstanding refcount %d.\n", ref); + ok(teststream.refcount == 1, "Got outstanding refcount %d.\n", teststream.refcount);
/* The return parameter is optional. */
From: Anton Baskanov baskanov@gmail.com
Signed-off-by: Anton Baskanov baskanov@gmail.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: change TRACE message format, use the name "filter" instead of "This", factor the check for redundant state setting into set_state(), and add a trace to stream_SetState().
dlls/amstream/filter.c | 48 +++++++++++-- dlls/amstream/tests/amstream.c | 124 +++++++++++++++++++++++++++++++-- 2 files changed, 162 insertions(+), 10 deletions(-)
diff --git a/dlls/amstream/filter.c b/dlls/amstream/filter.c index 1cb2ca71bac..fb9b1d9aee5 100644 --- a/dlls/amstream/filter.c +++ b/dlls/amstream/filter.c @@ -242,25 +242,61 @@ static HRESULT WINAPI filter_GetClassID(IMediaStreamFilter *iface, CLSID *clsid) return S_OK; }
+static void set_state(struct filter *filter, FILTER_STATE state) +{ + if (filter->state != state) + { + ULONG i; + + for (i = 0; i < filter->nb_streams; ++i) + IAMMediaStream_SetState(filter->streams[i], state); + filter->state = state; + } +} + static HRESULT WINAPI filter_Stop(IMediaStreamFilter *iface) { - FIXME("(%p)->(): Stub!\n", iface); + struct filter *filter = impl_from_IMediaStreamFilter(iface);
- return E_NOTIMPL; + TRACE("iface %p.\n", iface); + + EnterCriticalSection(&filter->cs); + + set_state(filter, State_Stopped); + + LeaveCriticalSection(&filter->cs); + + return S_OK; }
static HRESULT WINAPI filter_Pause(IMediaStreamFilter *iface) { - FIXME("(%p)->(): Stub!\n", iface); + struct filter *filter = impl_from_IMediaStreamFilter(iface);
- return E_NOTIMPL; + TRACE("iface %p.\n", iface); + + EnterCriticalSection(&filter->cs); + + set_state(filter, State_Paused); + + LeaveCriticalSection(&filter->cs); + + return S_OK; }
static HRESULT WINAPI filter_Run(IMediaStreamFilter *iface, REFERENCE_TIME start) { - FIXME("(%p)->(%s): Stub!\n", iface, wine_dbgstr_longlong(start)); + struct filter *filter = impl_from_IMediaStreamFilter(iface);
- return E_NOTIMPL; + TRACE("iface %p, start %s.\n", iface, wine_dbgstr_longlong(start)); + + EnterCriticalSection(&filter->cs); + + set_state(filter, State_Running); + + LeaveCriticalSection(&filter->cs); + + return S_OK; }
static HRESULT WINAPI filter_GetState(IMediaStreamFilter *iface, DWORD timeout, FILTER_STATE *state) diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 02fea447d0c..82a833ad6f9 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -311,9 +311,12 @@ struct teststream IAMMediaStream IAMMediaStream_iface; IPin IPin_iface; LONG refcount; + GUID mspid; IAMMultiMediaStream *mmstream; IMediaStreamFilter *filter; IFilterGraph *graph; + FILTER_STATE state; + HRESULT set_state_result; };
static struct teststream *impl_from_IAMMediaStream(IAMMediaStream *iface) @@ -500,9 +503,12 @@ static HRESULT WINAPI stream_GetMultiMediaStream(IAMMediaStream *iface, IMultiMe
static HRESULT WINAPI stream_GetInformation(IAMMediaStream *iface, MSPID *id, STREAM_TYPE *type) { + struct teststream *stream = impl_from_IAMMediaStream(iface); if (winetest_debug > 1) trace("GetInformation(%p, %p)\n", id, type); - *id = test_mspid; - ok(!type, "Got unexpected type %p.\n", type); + if (id) + *id = stream->mspid; + if (type) + *type = STREAMTYPE_READ; return S_OK; }
@@ -540,8 +546,11 @@ static HRESULT WINAPI stream_Initialize(IAMMediaStream *iface, IUnknown *source,
static HRESULT WINAPI stream_SetState(IAMMediaStream *iface, FILTER_STATE state) { - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; + struct teststream *stream = impl_from_IAMMediaStream(iface); + if (winetest_debug > 1) trace("SetState(%#x)\n", state); + if (SUCCEEDED(stream->set_state_result)) + stream->state = state; + return stream->set_state_result; }
static HRESULT WINAPI stream_JoinAMMultiMediaStream(IAMMediaStream *iface, IAMMultiMediaStream *mmstream) @@ -592,6 +601,8 @@ static void teststream_init(struct teststream *stream) stream->IAMMediaStream_iface.lpVtbl = &stream_vtbl; stream->IPin_iface.lpVtbl = &pin_vtbl; stream->refcount = 1; + stream->mspid = test_mspid; + stream->set_state_result = S_OK; }
#define check_enum_stream(a,b,c,d) check_enum_stream_(__LINE__,a,b,c,d) @@ -2800,6 +2811,110 @@ void test_mediastreamfilter_get_state(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+void check_mediastreamfilter_state(FILTER_STATE expected_state, HRESULT (*set_state)(IMediaStreamFilter *), + HRESULT (*reset_state)(IMediaStreamFilter *)) +{ + IAMMultiMediaStream *mmstream = create_ammultimediastream(); + struct teststream teststream, teststream2; + IMediaStreamFilter *filter; + FILTER_STATE state; + HRESULT hr; + ULONG ref; + + teststream_init(&teststream); + teststream_init(&teststream2); + + teststream2.mspid.Data2 = 1; + + hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream, &teststream.mspid, 0, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream2, &teststream2.mspid, 0, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IAMMultiMediaStream_GetFilter(mmstream, &filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter != NULL, "Expected non-null filter\n"); + + hr = reset_state(filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + teststream.state = 0xcc; + teststream2.state = 0xcc; + hr = set_state(filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(teststream.state == expected_state, "Got state %#x.\n", teststream.state); + ok(teststream2.state == expected_state, "Got state %#x.\n", teststream2.state); + hr = IMediaStreamFilter_GetState(filter, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(state == expected_state, "Got state %#x.\n", state); + + teststream.state = 0xcc; + teststream2.state = 0xcc; + hr = set_state(filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state); + ok(teststream2.state == 0xcc, "Got state %#x.\n", teststream2.state); + + hr = reset_state(filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + teststream.set_state_result = E_FAIL; + teststream.state = 0xcc; + teststream2.state = 0xcc; + hr = set_state(filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state); + ok(teststream2.state == expected_state, "Got state %#x.\n", teststream2.state); + hr = IMediaStreamFilter_GetState(filter, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(state == expected_state, "Got state %#x.\n", state); + + hr = reset_state(filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + teststream.set_state_result = E_FAIL; + teststream2.set_state_result = E_FAIL; + teststream.state = 0xcc; + teststream2.state = 0xcc; + hr = set_state(filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state); + ok(teststream2.state == 0xcc, "Got state %#x.\n", teststream2.state); + hr = IMediaStreamFilter_GetState(filter, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(state == expected_state, "Got state %#x.\n", state); + + ref = IAMMultiMediaStream_Release(mmstream); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IMediaStreamFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ok(teststream.refcount == 1, "Got outstanding refcount %d.\n", teststream.refcount); + ok(teststream2.refcount == 1, "Got outstanding refcount %d.\n", teststream2.refcount); +} + +static HRESULT mediastreamfilter_stop(IMediaStreamFilter *filter) +{ + return IMediaStreamFilter_Stop(filter); +} + +static HRESULT mediastreamfilter_pause(IMediaStreamFilter *filter) +{ + return IMediaStreamFilter_Pause(filter); +} + +static HRESULT mediastreamfilter_run(IMediaStreamFilter *filter) +{ + return IMediaStreamFilter_Run(filter, 0); +} + +void test_mediastreamfilter_stop_pause_run(void) +{ + check_mediastreamfilter_state(State_Stopped, mediastreamfilter_stop, mediastreamfilter_run); + check_mediastreamfilter_state(State_Paused, mediastreamfilter_pause, mediastreamfilter_stop); + check_mediastreamfilter_state(State_Running, mediastreamfilter_run, mediastreamfilter_stop); +} + START_TEST(amstream) { HANDLE file; @@ -2838,6 +2953,7 @@ START_TEST(amstream) test_audiostream_receive_connection();
test_mediastreamfilter_get_state(); + test_mediastreamfilter_stop_pause_run();
CoUninitialize(); }