Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/filter.c | 42 +++++++++++++++++++- dlls/amstream/tests/amstream.c | 72 +++++++++++++++++----------------- 2 files changed, 76 insertions(+), 38 deletions(-)
diff --git a/dlls/amstream/filter.c b/dlls/amstream/filter.c index 3c0436a294f..081e6b29ed5 100644 --- a/dlls/amstream/filter.c +++ b/dlls/amstream/filter.c @@ -178,6 +178,7 @@ struct filter REFERENCE_TIME start_time; struct list free_events; struct list used_events; + LONG eos_count; };
struct event @@ -266,6 +267,22 @@ static HRESULT WINAPI filter_GetClassID(IMediaStreamFilter *iface, CLSID *clsid) return S_OK; }
+static void send_ec_complete(struct filter *filter) +{ + IMediaEventSink *event_sink; + + if (!filter->graph) + return; + + if (FAILED(IFilterGraph_QueryInterface(filter->graph, &IID_IMediaEventSink, (void **)&event_sink))) + return; + + IMediaEventSink_Notify(event_sink, EC_COMPLETE, S_OK, + (LONG_PTR)&filter->IMediaStreamFilter_iface); + + IMediaEventSink_Release(event_sink); +} + static void set_state(struct filter *filter, FILTER_STATE state) { if (filter->state != state) @@ -287,6 +304,9 @@ static HRESULT WINAPI filter_Stop(IMediaStreamFilter *iface)
EnterCriticalSection(&filter->cs);
+ if (filter->state != State_Stopped) + filter->eos_count = 0; + set_state(filter, State_Stopped);
LIST_FOR_EACH_ENTRY(event, &filter->used_events, struct event, entry) @@ -327,6 +347,10 @@ static HRESULT WINAPI filter_Run(IMediaStreamFilter *iface, REFERENCE_TIME start
EnterCriticalSection(&filter->cs);
+ if (filter->state != State_Running && filter->seekable_stream + && filter->eos_count == (LONG)filter->nb_streams) + send_ec_complete(filter); + filter->start_time = start; set_state(filter, State_Running);
@@ -769,6 +793,9 @@ static HRESULT WINAPI filter_Flush(IMediaStreamFilter *iface, BOOL cancel_eos) } }
+ if (cancel_eos) + --filter->eos_count; + LeaveCriticalSection(&filter->cs);
return S_OK; @@ -776,9 +803,20 @@ static HRESULT WINAPI filter_Flush(IMediaStreamFilter *iface, BOOL cancel_eos)
static HRESULT WINAPI filter_EndOfStream(IMediaStreamFilter *iface) { - FIXME("(%p)->(): Stub!\n", iface); + struct filter *filter = impl_from_IMediaStreamFilter(iface);
- return E_NOTIMPL; + TRACE("filter %p.\n", filter); + + EnterCriticalSection(&filter->cs); + + ++filter->eos_count; + if (filter->state == State_Running && filter->seekable_stream && + filter->eos_count == (LONG)filter->nb_streams) + send_ec_complete(filter); + + LeaveCriticalSection(&filter->cs); + + return S_OK; }
static const IMediaStreamFilterVtbl filter_vtbl = diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 79cc4f52801..9cefec12442 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -6954,9 +6954,9 @@ static void test_mediastreamfilter_end_of_stream(void) graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
@@ -6973,9 +6973,9 @@ static void test_mediastreamfilter_end_of_stream(void) graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
@@ -6994,14 +6994,14 @@ static void test_mediastreamfilter_end_of_stream(void) graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -7011,9 +7011,9 @@ static void test_mediastreamfilter_end_of_stream(void) graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
@@ -7025,12 +7025,12 @@ static void test_mediastreamfilter_end_of_stream(void) hr = IMediaControl_Run(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaControl_Run(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaControl_Stop(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -7040,9 +7040,9 @@ static void test_mediastreamfilter_end_of_stream(void) graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
@@ -7054,7 +7054,7 @@ static void test_mediastreamfilter_end_of_stream(void) hr = IMediaControl_Run(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaControl_Stop(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -7066,7 +7066,7 @@ static void test_mediastreamfilter_end_of_stream(void) graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -7074,7 +7074,7 @@ static void test_mediastreamfilter_end_of_stream(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
@@ -7088,7 +7088,7 @@ static void test_mediastreamfilter_end_of_stream(void) graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_Pause(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -7096,29 +7096,29 @@ static void test_mediastreamfilter_end_of_stream(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaControl_Stop(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr);
/* EndOfStream count is not reset when Stop() is called on an already stopped filter. */ hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_Stop(filter); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
graph.got_notify = 0;
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN); ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -7130,12 +7130,12 @@ static void test_mediastreamfilter_end_of_stream(void) graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_Flush(filter, TRUE);
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
@@ -7149,19 +7149,19 @@ static void test_mediastreamfilter_end_of_stream(void) graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaStreamFilter_Flush(filter, TRUE); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(graph.got_notify == 2, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 2, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -7176,16 +7176,16 @@ static void test_mediastreamfilter_end_of_stream(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(graph.got_notify == 0, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -7197,14 +7197,14 @@ static void test_mediastreamfilter_end_of_stream(void) graph.got_notify = 0;
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStreamFilter_Flush(filter, FALSE);
hr = IMediaStreamFilter_EndOfStream(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify); + ok(graph.got_notify == 1, "Got %d calls to IMediaEventSink::Notify().\n", graph.got_notify);
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); ok(hr == S_OK, "Got hr %#x.\n", hr);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88550
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/amstream/tests/amstream.c:7025 Task: Patch failed to apply
=== debiant2 (build log) ===
error: patch failed: dlls/amstream/tests/amstream.c:7025 Task: Patch failed to apply
=== debiant2 (build log) ===
error: patch failed: dlls/amstream/tests/amstream.c:7025 Task: Patch failed to apply