[PATCH 4/5] qcap/filewriter: Post EC_COMPLETE on receiving EOS.
Zebediah Figura
z.figura12 at gmail.com
Thu Apr 23 17:53:05 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 d4452766a1..a24438ce51 100644
--- a/dlls/qcap/tests/filewriter.c
+++ b/dlls/qcap/tests/filewriter.c
@@ -685,6 +685,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, ¶m1, ¶m2, 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 =
@@ -745,6 +796,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