[PATCH 2/3] amstream: Implement MediaStreamFilter::EndOfStream.

Anton Baskanov baskanov at gmail.com
Fri Apr 9 14:02:56 CDT 2021


Signed-off-by: Anton Baskanov <baskanov at 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..881ddb114e2 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)
@@ -275,6 +292,13 @@ static void set_state(struct filter *filter, FILTER_STATE state)
         for (i = 0; i < filter->nb_streams; ++i)
             IAMMediaStream_SetState(filter->streams[i], state);
         filter->state = state;
+
+        if (state == State_Stopped)
+            filter->eos_count = 0;
+
+        if (state == State_Running && filter->seekable_stream
+                && filter->eos_count == (LONG)filter->nb_streams)
+            send_ec_complete(filter);
     }
 }
 
@@ -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);
-- 
2.25.1




More information about the wine-devel mailing list