Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/filewriter.c | 26 +++++++++++++++ dlls/qcap/tests/filewriter.c | 62 ++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 2 deletions(-)
diff --git a/dlls/qcap/filewriter.c b/dlls/qcap/filewriter.c index aa58226bd0..caec4936cf 100644 --- a/dlls/qcap/filewriter.c +++ b/dlls/qcap/filewriter.c @@ -34,6 +34,7 @@ struct file_writer struct strmbase_sink sink;
WCHAR *filename; + HANDLE file; };
static inline struct file_writer *impl_from_strmbase_pin(struct strmbase_pin *iface) @@ -106,11 +107,36 @@ static void file_writer_destroy(struct strmbase_filter *iface) heap_free(filter); }
+static HRESULT file_writer_init_stream(struct strmbase_filter *iface) +{ + struct file_writer *filter = impl_from_strmbase_filter(iface); + HANDLE file; + + if ((file = CreateFileW(filter->filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE) + { + ERR("Failed to create %s, error %u.\n", debugstr_w(filter->filename), GetLastError()); + return HRESULT_FROM_WIN32(GetLastError()); + } + filter->file = file; + return S_OK; +} + +static HRESULT file_writer_cleanup_stream(struct strmbase_filter *iface) +{ + struct file_writer *filter = impl_from_strmbase_filter(iface); + + CloseHandle(filter->file); + return S_OK; +} + static struct strmbase_filter_ops filter_ops = { .filter_query_interface = file_writer_query_interface, .filter_get_pin = file_writer_get_pin, .filter_destroy = file_writer_destroy, + .filter_init_stream = file_writer_init_stream, + .filter_cleanup_stream = file_writer_cleanup_stream, };
static inline struct file_writer *impl_from_IFileSinkFilter(IFileSinkFilter *iface) diff --git a/dlls/qcap/tests/filewriter.c b/dlls/qcap/tests/filewriter.c index cfc9e5d634..57bd2ec872 100644 --- a/dlls/qcap/tests/filewriter.c +++ b/dlls/qcap/tests/filewriter.c @@ -564,6 +564,58 @@ static void test_allocator(IMemInputPin *input, IMemAllocator *allocator) IMemAllocator_Release(ret_allocator); }
+static void test_filter_state(IMediaControl *control) +{ + OAFilterState state; + HRESULT hr; + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(state == State_Stopped, "Got state %u.\n", state); + + hr = IMediaControl_Pause(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(state == State_Paused, "Got state %u.\n", state); + + hr = IMediaControl_Run(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(state == State_Running, "Got state %u.\n", state); + + hr = IMediaControl_Pause(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(state == State_Paused, "Got state %u.\n", state); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(state == State_Stopped, "Got state %u.\n", state); + + hr = IMediaControl_Run(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(state == State_Running, "Got state %u.\n", state); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(state == State_Stopped, "Got state %u.\n", state); +} + static void test_connect_pin(void) { AM_MEDIA_TYPE req_mt = @@ -574,19 +626,21 @@ static void test_connect_pin(void) };
IBaseFilter *filter = create_file_writer(); + WCHAR *filename = set_filename(filter); struct testfilter source; IMemAllocator *allocator; + IMediaControl *control; IMemInputPin *meminput; IFilterGraph2 *graph; AM_MEDIA_TYPE mt; IPin *pin, *peer; HRESULT hr; ULONG ref; - - set_filename(filter); + BOOL ret;
testfilter_init(&source); CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterGraph2, (void **)&graph); + IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control); hr = IFilterGraph2_AddFilter(graph, filter, L"filewriter"); ok(hr == S_OK, "Got hr %#x.\n", hr); IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source"); @@ -620,6 +674,7 @@ static void test_connect_pin(void) &IID_IMemAllocator, (void **)&allocator);
test_allocator(meminput, allocator); + test_filter_state(control);
hr = IFilterGraph2_Disconnect(graph, pin); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -636,6 +691,9 @@ static void test_connect_pin(void) hr = IPin_ConnectionMediaType(pin, &mt); ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr);
+ ret = DeleteFileW(filename); + ok(ret, "Failed to delete file, error %u.\n", GetLastError()); + IMediaControl_Release(control); ref = IFilterGraph2_Release(graph); ok(!ref, "Got outstanding refcount %d.\n", ref); IMemInputPin_Release(meminput);