Signed-off-by: Zebediah Figura z.figura12@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, ¶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 = @@ -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);