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);