[PATCH 3/5] quartz/tests: Add some tests for sample presentation time on the VMR9.
Zebediah Figura
z.figura12 at gmail.com
Thu Apr 30 21:51:45 CDT 2020
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/quartz/tests/vmr9.c | 154 ++++++++++++++++++++++++++++-----------
1 file changed, 111 insertions(+), 43 deletions(-)
diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c
index 9485d055f09..0e02de64522 100644
--- a/dlls/quartz/tests/vmr9.c
+++ b/dlls/quartz/tests/vmr9.c
@@ -964,13 +964,14 @@ static DWORD WINAPI frame_thread(void *arg)
return hr;
}
-static HANDLE send_frame(IMemInputPin *sink)
+static HANDLE send_frame_time(IMemInputPin *sink, REFERENCE_TIME start_time, DWORD color)
{
struct frame_thread_params *params = heap_alloc(sizeof(*params));
- REFERENCE_TIME start_time, end_time;
IMemAllocator *allocator;
+ REFERENCE_TIME end_time;
IMediaSample *sample;
HANDLE thread;
+ LONG size, i;
HRESULT hr;
BYTE *data;
@@ -980,14 +981,16 @@ static HANDLE send_frame(IMemInputPin *sink)
hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+ size = IMediaSample_GetSize(sample);
hr = IMediaSample_GetPointer(sample, &data);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- memset(data, 0x55, IMediaSample_GetSize(sample));
+ for (i = 0; i < size / sizeof(DWORD); ++i)
+ ((DWORD *)data)[i] = color;
- hr = IMediaSample_SetActualDataLength(sample, IMediaSample_GetSize(sample));
+ hr = IMediaSample_SetActualDataLength(sample, size);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- start_time = 0;
+ start_time *= 10000000;
end_time = start_time + 10000000;
hr = IMediaSample_SetTime(sample, &start_time, &end_time);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -1000,6 +1003,11 @@ static HANDLE send_frame(IMemInputPin *sink)
return thread;
}
+static HANDLE send_frame(IMemInputPin *sink)
+{
+ return send_frame_time(sink, 0, 0x007f007f);
+}
+
static HRESULT join_thread_(int line, HANDLE thread)
{
DWORD ret;
@@ -1010,17 +1018,26 @@ static HRESULT join_thread_(int line, HANDLE thread)
}
#define join_thread(a) join_thread_(__LINE__, a)
-static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph)
+static void commit_allocator(IMemInputPin *input)
+{
+ IMemAllocator *allocator;
+ HRESULT hr;
+
+ hr = IMemInputPin_GetAllocator(input, &allocator);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = IMemAllocator_Commit(allocator);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ IMemAllocator_Release(allocator);
+}
+
+static void test_filter_state(IMemInputPin *input, IMediaControl *control)
{
IMemAllocator *allocator;
- IMediaControl *control;
IMediaSample *sample;
OAFilterState state;
HANDLE thread;
HRESULT hr;
- IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
-
thread = send_frame(input);
hr = join_thread(thread);
ok(hr == VFW_E_WRONG_STATE, "Got hr %#x.\n", hr);
@@ -1122,9 +1139,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph)
hr = IMediaControl_GetState(control, 0, &state);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IMemAllocator_Commit(allocator);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
-
+ commit_allocator(input);
hr = IMediaControl_Pause(control);
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
@@ -1151,25 +1166,15 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph)
ok(hr == S_OK, "Got hr %#x.\n", hr);
IMemAllocator_Release(allocator);
- IMediaControl_Release(control);
}
-static void test_flushing(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph)
+static void test_flushing(IPin *pin, IMemInputPin *input, IMediaControl *control)
{
- IMemAllocator *allocator;
- IMediaControl *control;
OAFilterState state;
HANDLE thread;
HRESULT hr;
- IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
-
- hr = IMemInputPin_GetAllocator(input, &allocator);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IMemAllocator_Commit(allocator);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- IMemAllocator_Release(allocator);
-
+ commit_allocator(input);
hr = IMediaControl_Pause(control);
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
@@ -1221,19 +1226,85 @@ static void test_flushing(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph)
hr = IMediaControl_Stop(control);
ok(hr == S_OK, "Got hr %#x.\n", hr);
+}
- IMediaControl_Release(control);
+static void test_sample_time(IPin *pin, IMemInputPin *input, IMediaControl *control)
+{
+ OAFilterState state;
+ HANDLE thread;
+ HRESULT hr;
+
+ commit_allocator(input);
+ hr = IMediaControl_Pause(control);
+ ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+
+ hr = IMediaControl_GetState(control, 0, &state);
+ ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
+
+ thread = send_frame_time(input, 1, 0x000000ff); /* blue */
+
+ hr = IMediaControl_GetState(control, 1000, &state);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
+
+ hr = IMediaControl_Run(control);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ ok(WaitForSingleObject(thread, 500) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
+
+ hr = join_thread(thread);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ /* Sample time is relative to the time passed to Run(). Thus a sample
+ * stamped at or earlier than 1s will now be displayed immediately, because
+ * that time has already passed.
+ * One may manually verify that all of the frames in this function are
+ * rendered, including (by adding a Sleep() after sending the frame) the
+ * cyan and green frames. Thus the VMR does not attempt to drop any frames
+ * that it considers late. This remains true if the frames are marked as
+ * discontinuous. */
+
+ hr = join_thread(send_frame_time(input, 1, 0x0000ffff)); /* cyan */
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = join_thread(send_frame_time(input, 0, 0x0000ff00)); /* green */
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = join_thread(send_frame_time(input, -2, 0x00ff0000)); /* red */
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ thread = send_frame_time(input, 2, 0x00ff00ff); /* magenta */
+ ok(WaitForSingleObject(thread, 800) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
+ hr = join_thread(thread);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ thread = send_frame_time(input, 1000000, 0x00ffffff); /* white */
+ ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
+
+ hr = IPin_BeginFlush(pin);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = join_thread(thread);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = IPin_EndFlush(pin);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ thread = send_frame_time(input, 1000000, 0x00ffff00); /* yellow */
+ ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
+
+ hr = IMediaControl_Stop(control);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = join_thread(thread);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
}
static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
- IFilterGraph2 *graph, const BITMAPINFOHEADER *req_bih)
+ IMediaControl *control, const BITMAPINFOHEADER *req_bih)
{
LONG buffer[(sizeof(BITMAPINFOHEADER) + 32 * 16 * 4) / 4];
const BITMAPINFOHEADER *bih = (BITMAPINFOHEADER *)buffer;
const DWORD *data = (DWORD *)((char *)buffer + sizeof(BITMAPINFOHEADER));
BITMAPINFOHEADER expect_bih = *req_bih;
- IMemAllocator *allocator;
- IMediaControl *control;
OAFilterState state;
IBasicVideo *video;
unsigned int i;
@@ -1243,7 +1314,6 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
expect_bih.biSizeImage = 32 * 16 * 4;
- IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
IBaseFilter_QueryInterface(filter, &IID_IBasicVideo, (void **)&video);
hr = IBasicVideo_GetCurrentImage(video, NULL, NULL);
@@ -1264,12 +1334,7 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
/* The contents seem to reflect the last frame rendered. */
- hr = IMemInputPin_GetAllocator(input, &allocator);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IMemAllocator_Commit(allocator);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- IMemAllocator_Release(allocator);
-
+ commit_allocator(input);
hr = IMediaControl_Pause(control);
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
@@ -1299,7 +1364,7 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
if (0) /* FIXME: Rendering is currently broken on Wine. */
{
for (i = 0; i < 32 * 16; ++i)
- ok((data[i] & 0xffffff) == 0x555555, "Got unexpected color %08x at %u.\n", data[i], i);
+ ok((data[i] & 0xffffff) == 0x7f007f, "Got unexpected color %08x at %u.\n", data[i], i);
}
hr = IMediaControl_Run(control);
@@ -1315,14 +1380,13 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
if (0) /* FIXME: Rendering is currently broken on Wine. */
{
for (i = 0; i < 32 * 16; ++i)
- ok((data[i] & 0xffffff) == 0x555555, "Got unexpected color %08x at %u.\n", data[i], i);
+ ok((data[i] & 0xffffff) == 0x7f007f, "Got unexpected color %08x at %u.\n", data[i], i);
}
hr = IMediaControl_Stop(control);
ok(hr == S_OK, "Got hr %#x.\n", hr);
IBasicVideo_Release(video);
- IMediaControl_Release(control);
}
static void test_connect_pin(void)
@@ -1348,6 +1412,7 @@ static void test_connect_pin(void)
IFilterGraph2 *graph = create_graph();
struct testfilter source;
IMemAllocator *allocator;
+ IMediaControl *control;
IMemInputPin *input;
unsigned int i, j;
AM_MEDIA_TYPE mt;
@@ -1368,6 +1433,7 @@ static void test_connect_pin(void)
IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
IFilterGraph2_AddFilter(graph, filter, NULL);
+ IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
@@ -1453,9 +1519,10 @@ static void test_connect_pin(void)
hr = IMemInputPin_ReceiveCanBlock(input);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- test_filter_state(input, graph);
- test_flushing(pin, input, graph);
- test_current_image(filter, input, graph, &vih.bmiHeader);
+ test_filter_state(input, control);
+ test_flushing(pin, input, control);
+ test_sample_time(pin, input, control);
+ test_current_image(filter, input, control, &vih.bmiHeader);
hr = IFilterGraph2_Disconnect(graph, pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -1473,10 +1540,11 @@ static void test_connect_pin(void)
ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr);
out:
- IMemInputPin_Release(input);
- IPin_Release(pin);
+ IMediaControl_Release(control);
ref = IFilterGraph2_Release(graph);
ok(!ref, "Got outstanding refcount %d.\n", ref);
+ IMemInputPin_Release(input);
+ IPin_Release(pin);
ref = IBaseFilter_Release(filter);
ok(!ref, "Got outstanding refcount %d.\n", ref);
ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
--
2.26.2
More information about the wine-devel
mailing list