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);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/filewriter.c | 26 ++++++++++++++ dlls/qcap/tests/filewriter.c | 70 ++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+)
diff --git a/dlls/qcap/filewriter.c b/dlls/qcap/filewriter.c index caec4936cf..2a3c8df4b9 100644 --- a/dlls/qcap/filewriter.c +++ b/dlls/qcap/filewriter.c @@ -64,10 +64,36 @@ static HRESULT file_writer_sink_query_accept(struct strmbase_pin *iface, const A return S_OK; }
+static HRESULT WINAPI file_writer_sink_receive(struct strmbase_sink *iface, IMediaSample *sample) +{ + struct file_writer *filter = impl_from_strmbase_pin(&iface->pin); + REFERENCE_TIME start, stop; + LARGE_INTEGER offset; + HRESULT hr; + DWORD size; + BYTE *data; + + if ((hr = IMediaSample_GetTime(sample, &start, &stop)) != S_OK) + ERR("Failed to get sample time, hr %#x.\n", hr); + + if ((hr = IMediaSample_GetPointer(sample, &data)) != S_OK) + ERR("Failed to get sample pointer, hr %#x.\n", hr); + + offset.QuadPart = start; + if (!SetFilePointerEx(filter->file, offset, NULL, FILE_BEGIN) + || !WriteFile(filter->file, data, stop - start, &size, NULL)) + ERR("Failed to write file, error %u.\n", GetLastError()); + if (size != stop - start) + ERR("Short write, %u/%u.\n", size, (DWORD)(stop - start)); + + 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, };
static inline struct file_writer *impl_from_strmbase_filter(struct strmbase_filter *iface) diff --git a/dlls/qcap/tests/filewriter.c b/dlls/qcap/tests/filewriter.c index 57bd2ec872..4a453d3267 100644 --- a/dlls/qcap/tests/filewriter.c +++ b/dlls/qcap/tests/filewriter.c @@ -616,6 +616,75 @@ static void test_filter_state(IMediaControl *control) ok(state == State_Stopped, "Got state %u.\n", state); }
+static void test_sample_processing(IMediaControl *control, IMemInputPin *input, + IMemAllocator *allocator, const WCHAR *filename) +{ + REFERENCE_TIME start, stop; + IMediaSample *sample; + BYTE buffer[20]; + FILE *file; + HRESULT hr; + BYTE *data; + LONG size; + + hr = IMemInputPin_ReceiveCanBlock(input); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Pause(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0); + ok(hr == VFW_E_NOT_COMMITTED, "Got hr %#x.\n", hr); + + hr = IMemAllocator_Commit(allocator); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaSample_GetPointer(sample, &data); + ok(hr == S_OK, "Got hr %#x.\n", hr); + size = IMediaSample_GetSize(sample); + ok(size == 256, "Got size %d.\n", size); + memset(data, 0xcc, size); + strcpy((char *)data, "abcdef"); + hr = IMediaSample_SetActualDataLength(sample, 6); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + start = 3; + stop = 15; + hr = IMediaSample_SetTime(sample, &start, &stop); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMemInputPin_Receive(input, sample); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + start = 9; + stop = 11; + hr = IMediaSample_SetTime(sample, &start, &stop); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMemInputPin_Receive(input, sample); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + start = 0; + stop = 6; + hr = IMediaSample_SetTime(sample, &start, &stop); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMemInputPin_Receive(input, sample); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + file = _wfopen(filename, L"rb"); + ok(!!file, "Failed to open file: %s.\n", strerror(errno)); + size = fread(buffer, 1, sizeof(buffer), file); + ok(size == 15, "Got size %d.\n", size); + ok(!memcmp(buffer, "abcdefdefab\xcc\xcc\xcc\xcc", 15), "Got data %s.\n", + debugstr_an((char *)buffer, size)); + fclose(file); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IMediaSample_Release(sample); +} + static void test_connect_pin(void) { AM_MEDIA_TYPE req_mt = @@ -675,6 +744,7 @@ static void test_connect_pin(void)
test_allocator(meminput, allocator); test_filter_state(control); + test_sample_processing(control, meminput, allocator, filename);
hr = IFilterGraph2_Disconnect(graph, pin); ok(hr == S_OK, "Got hr %#x.\n", hr);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70392
Your paranoid android.
=== wxppro (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w2008s64 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w8 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w8adm (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1507 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_2scr (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_ar (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_he (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_ja (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_zh_CN (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w2008s64 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w864 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1507 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/filewriter.c | 46 +++++++++++++++++++++++++++++++++++- dlls/qcap/tests/filewriter.c | 19 ++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/dlls/qcap/filewriter.c b/dlls/qcap/filewriter.c index 2a3c8df4b9..4d9262e757 100644 --- a/dlls/qcap/filewriter.c +++ b/dlls/qcap/filewriter.c @@ -29,6 +29,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(qcap); struct file_writer { struct strmbase_filter filter; + IAMFilterMiscFlags IAMFilterMiscFlags_iface; IFileSinkFilter IFileSinkFilter_iface;
struct strmbase_sink sink; @@ -105,7 +106,9 @@ static HRESULT file_writer_query_interface(struct strmbase_filter *iface, REFIID { struct file_writer *filter = impl_from_strmbase_filter(iface);
- if (IsEqualGUID(iid, &IID_IFileSinkFilter)) + if (IsEqualGUID(iid, &IID_IAMFilterMiscFlags)) + *out = &filter->IAMFilterMiscFlags_iface; + else if (IsEqualGUID(iid, &IID_IFileSinkFilter)) *out = &filter->IFileSinkFilter_iface; else return E_NOINTERFACE; @@ -228,6 +231,46 @@ static const IFileSinkFilterVtbl filesinkfilter_vtbl = filesinkfilter_GetCurFile, };
+static inline struct file_writer *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface) +{ + return CONTAINING_RECORD(iface, struct file_writer, IAMFilterMiscFlags_iface); +} + +static HRESULT WINAPI misc_flags_QueryInterface(IAMFilterMiscFlags *iface, REFIID iid, void **out) +{ + struct file_writer *filter = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_QueryInterface(filter->filter.outer_unk, iid, out); +} + +static ULONG WINAPI misc_flags_AddRef(IAMFilterMiscFlags *iface) +{ + struct file_writer *filter = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_AddRef(filter->filter.outer_unk); +} + +static ULONG WINAPI misc_flags_Release(IAMFilterMiscFlags *iface) +{ + struct file_writer *filter = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_Release(filter->filter.outer_unk); +} + +static ULONG WINAPI misc_flags_GetMiscFlags(IAMFilterMiscFlags *iface) +{ + struct file_writer *filter = impl_from_IAMFilterMiscFlags(iface); + + TRACE("filter %p.\n", filter); + + return AM_FILTER_MISC_FLAGS_IS_RENDERER; +} + +static const IAMFilterMiscFlagsVtbl misc_flags_vtbl = +{ + misc_flags_QueryInterface, + misc_flags_AddRef, + misc_flags_Release, + misc_flags_GetMiscFlags, +}; + HRESULT file_writer_create(IUnknown *outer, IUnknown **out) { static const WCHAR sink_name[] = {'i','n',0}; @@ -238,6 +281,7 @@ HRESULT file_writer_create(IUnknown *outer, IUnknown **out)
strmbase_filter_init(&object->filter, outer, &CLSID_FileWriter, &filter_ops); object->IFileSinkFilter_iface.lpVtbl = &filesinkfilter_vtbl; + object->IAMFilterMiscFlags_iface.lpVtbl = &misc_flags_vtbl;
strmbase_sink_init(&object->sink, &object->filter, sink_name, &sink_ops, NULL);
diff --git a/dlls/qcap/tests/filewriter.c b/dlls/qcap/tests/filewriter.c index 4a453d3267..d4452766a1 100644 --- a/dlls/qcap/tests/filewriter.c +++ b/dlls/qcap/tests/filewriter.c @@ -78,7 +78,7 @@ static void test_interfaces(void) ULONG ref; IPin *pin;
- todo_wine check_interface(filter, &IID_IAMFilterMiscFlags, TRUE); + check_interface(filter, &IID_IAMFilterMiscFlags, TRUE); check_interface(filter, &IID_IBaseFilter, TRUE); check_interface(filter, &IID_IFileSinkFilter, TRUE); todo_wine check_interface(filter, &IID_IFileSinkFilter2, TRUE); @@ -776,6 +776,22 @@ static void test_connect_pin(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void test_misc_flags(void) +{ + IBaseFilter *filter = create_file_writer(); + IAMFilterMiscFlags *misc_flags; + ULONG flags, ref; + + IBaseFilter_QueryInterface(filter, &IID_IAMFilterMiscFlags, (void **)&misc_flags); + + flags = IAMFilterMiscFlags_GetMiscFlags(misc_flags); + ok(flags == AM_FILTER_MISC_FLAGS_IS_RENDERER, "Got flags %#x.\n", flags); + + IAMFilterMiscFlags_Release(misc_flags); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + START_TEST(filewriter) { CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -788,6 +804,7 @@ START_TEST(filewriter) test_media_types(); test_enum_media_types(); test_connect_pin(); + test_misc_flags();
CoUninitialize(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70393
Your paranoid android.
=== wxppro (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w2008s64 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w8 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w8adm (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1507 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_2scr (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_ar (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_he (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_ja (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_zh_CN (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w2008s64 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w864 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1507 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
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 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);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70394
Your paranoid android.
=== wxppro (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w2008s64 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w8 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w8adm (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1507 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809 (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_2scr (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_ar (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_he (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_ja (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809_zh_CN (32 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w2008s64 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w864 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1507 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
=== w1064v1809 (64 bit report) ===
qcap: filewriter.c:648: Test failed: Got size 512. filewriter.c:659: Test failed: Got hr 0x80070057. filewriter.c:666: Test failed: Got hr 0x1. filewriter.c:673: Test failed: Got hr 0x1. filewriter.c:678: Test failed: Got size 0. filewriter.c:679: Test failed: Got data "".
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/qcap_main.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/dlls/qcap/qcap_main.c b/dlls/qcap/qcap_main.c index 2f45e2f469..00e0a9671f 100644 --- a/dlls/qcap/qcap_main.c +++ b/dlls/qcap/qcap_main.c @@ -224,12 +224,32 @@ static const REGFILTER2 reg_smart_tee = .u.s2.rgPins2 = reg_smart_tee_pins, };
+static const REGPINTYPES reg_file_writer_sink_mt = {&GUID_NULL, &GUID_NULL}; + +static const REGFILTERPINS2 reg_file_writer_pins[1] = +{ + { + .cInstances = 1, + .nMediaTypes = 1, + .lpMediaType = ®_file_writer_sink_mt, + }, +}; + +static const REGFILTER2 reg_file_writer = +{ + .dwVersion = 2, + .dwMerit = MERIT_DO_NOT_USE, + .u.s2.cPins2 = 1, + .u.s2.rgPins2 = reg_file_writer_pins, +}; + /*********************************************************************** * DllRegisterServer (QCAP.@) */ HRESULT WINAPI DllRegisterServer(void) { static const WCHAR avi_muxW[] = {'A','V','I',' ','M','u','x',0}; + static const WCHAR file_writerW[] = {'F','i','l','e',' ','w','r','i','t','e','r',0}; static const WCHAR smart_teeW[] = {'S','m','a','r','t',' ','T','e','e',0}; IFilterMapper2 *mapper; HRESULT hr; @@ -243,6 +263,8 @@ HRESULT WINAPI DllRegisterServer(void)
IFilterMapper2_RegisterFilter(mapper, &CLSID_AviDest, avi_muxW, NULL, NULL, NULL, ®_avi_mux); + IFilterMapper2_RegisterFilter(mapper, &CLSID_FileWriter, file_writerW, + NULL, NULL, NULL, ®_file_writer); IFilterMapper2_RegisterFilter(mapper, &CLSID_SmartTee, smart_teeW, NULL, NULL, NULL, ®_smart_tee);
@@ -266,6 +288,7 @@ HRESULT WINAPI DllUnregisterServer(void) return hr;
IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_AviDest); + IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_FileWriter); IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_SmartTee);
IFilterMapper2_Release(mapper);