[PATCH v3 4/5] qcap/filewriter: Post EC_COMPLETE on receiving EOS.

Zebediah Figura z.figura12 at gmail.com
Thu Apr 23 20:47:07 CDT 2020


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/qcap/filewriter.c       | 42 +++++++++++++++++++++++++++++
 dlls/qcap/tests/filewriter.c | 52 ++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+)

diff --git a/dlls/qcap/filewriter.c b/dlls/qcap/filewriter.c
index 4d9262e757..5e63facf7b 100644
--- a/dlls/qcap/filewriter.c
+++ b/dlls/qcap/filewriter.c
@@ -36,6 +36,8 @@ struct file_writer
 
     WCHAR *filename;
     HANDLE file;
+
+    BOOL eos;
 };
 
 static inline struct file_writer *impl_from_strmbase_pin(struct strmbase_pin *iface)
@@ -90,11 +92,40 @@ static HRESULT WINAPI file_writer_sink_receive(struct strmbase_sink *iface, IMed
     return S_OK;
 }
 
+static void deliver_ec_complete(struct file_writer *filter)
+{
+    IMediaEventSink *event_sink;
+
+    if (SUCCEEDED(IFilterGraph_QueryInterface(filter->filter.graph,
+            &IID_IMediaEventSink, (void **)&event_sink)))
+    {
+        IMediaEventSink_Notify(event_sink, EC_COMPLETE, S_OK,
+                (LONG_PTR)&filter->filter.IBaseFilter_iface);
+        IMediaEventSink_Release(event_sink);
+    }
+}
+
+static HRESULT file_writer_sink_eos(struct strmbase_sink *iface)
+{
+    struct file_writer *filter = impl_from_strmbase_pin(&iface->pin);
+
+    EnterCriticalSection(&filter->filter.csFilter);
+
+    if (filter->filter.state == State_Running)
+        deliver_ec_complete(filter);
+    else
+        filter->eos = TRUE;
+
+    LeaveCriticalSection(&filter->filter.csFilter);
+    return S_OK;
+}
+
 static const struct strmbase_sink_ops sink_ops =
 {
     .base.pin_query_interface = file_writer_sink_query_interface,
     .base.pin_query_accept = file_writer_sink_query_accept,
     .pfnReceive = file_writer_sink_receive,
+    .sink_eos = file_writer_sink_eos,
 };
 
 static inline struct file_writer *impl_from_strmbase_filter(struct strmbase_filter *iface)
@@ -151,6 +182,16 @@ static HRESULT file_writer_init_stream(struct strmbase_filter *iface)
     return S_OK;
 }
 
+static HRESULT file_writer_start_stream(struct strmbase_filter *iface, REFERENCE_TIME start)
+{
+    struct file_writer *filter = impl_from_strmbase_filter(iface);
+
+    if (filter->eos)
+        deliver_ec_complete(filter);
+    filter->eos = FALSE;
+    return S_OK;
+}
+
 static HRESULT file_writer_cleanup_stream(struct strmbase_filter *iface)
 {
     struct file_writer *filter = impl_from_strmbase_filter(iface);
@@ -165,6 +206,7 @@ static struct strmbase_filter_ops filter_ops =
     .filter_get_pin = file_writer_get_pin,
     .filter_destroy = file_writer_destroy,
     .filter_init_stream = file_writer_init_stream,
+    .filter_start_stream = file_writer_start_stream,
     .filter_cleanup_stream = file_writer_cleanup_stream,
 };
 
diff --git a/dlls/qcap/tests/filewriter.c b/dlls/qcap/tests/filewriter.c
index 7e8a91d3fb..e3bdcb7656 100644
--- a/dlls/qcap/tests/filewriter.c
+++ b/dlls/qcap/tests/filewriter.c
@@ -678,6 +678,57 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input,
     IMediaSample_Release(sample);
 }
 
+static unsigned int check_ec_complete(IMediaEvent *eventsrc, DWORD timeout)
+{
+    LONG_PTR param1, param2;
+    unsigned int ret = 0;
+    HRESULT hr;
+    LONG code;
+
+    while ((hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, timeout)) == S_OK)
+    {
+        if (code == EC_COMPLETE)
+        {
+            ok(param1 == S_OK, "Got param1 %#lx.\n", param1);
+            ok(!param2, "Got param2 %#lx.\n", param2);
+            ret++;
+        }
+        IMediaEvent_FreeEventParams(eventsrc, code, param1, param2);
+        timeout = 0;
+    }
+    ok(hr == E_ABORT, "Got hr %#x.\n", hr);
+
+    return ret;
+}
+
+static void test_eos(IFilterGraph2 *graph, IMediaControl *control, IPin *pin)
+{
+    IMediaEvent *eventsrc;
+    HRESULT hr;
+    BOOL ret;
+
+    IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&eventsrc);
+
+    hr = IMediaControl_Pause(control);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ret = check_ec_complete(eventsrc, 0);
+    ok(!ret, "Got unexpected EC_COMPLETE.\n");
+
+    hr = IPin_EndOfStream(pin);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ret = check_ec_complete(eventsrc, 0);
+    ok(!ret, "Got unexpected EC_COMPLETE.\n");
+
+    hr = IMediaControl_Run(control);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ret = check_ec_complete(eventsrc, 0);
+    ok(ret == 1, "Expected EC_COMPLETE.\n");
+
+    hr = IMediaControl_Stop(control);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    IMediaEvent_Release(eventsrc);
+}
+
 static void test_connect_pin(void)
 {
     AM_MEDIA_TYPE req_mt =
@@ -738,6 +789,7 @@ static void test_connect_pin(void)
     test_allocator(meminput, allocator);
     test_filter_state(control);
     test_sample_processing(control, meminput, allocator, filename);
+    test_eos(graph, control, pin);
 
     hr = IFilterGraph2_Disconnect(graph, pin);
     ok(hr == S_OK, "Got hr %#x.\n", hr);
-- 
2.26.2




More information about the wine-devel mailing list