[PATCH 2/2] evr/mixer: Flush on MFT_MESSAGE_NOTIFY_END_STREAMING.
Nikolay Sivov
nsivov at codeweavers.com
Wed Nov 10 06:33:22 CST 2021
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/evr/mixer.c | 21 +++-----
dlls/evr/tests/evr.c | 121 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 128 insertions(+), 14 deletions(-)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c
index b9a28c4ad75..8fe80c2f4a9 100644
--- a/dlls/evr/mixer.c
+++ b/dlls/evr/mixer.c
@@ -1125,34 +1125,27 @@ static HRESULT WINAPI video_mixer_transform_ProcessMessage(IMFTransform *iface,
TRACE("%p, %#x, %#lx.\n", iface, message, param);
+ EnterCriticalSection(&mixer->cs);
+
switch (message)
{
case MFT_MESSAGE_SET_D3D_MANAGER:
-
- EnterCriticalSection(&mixer->cs);
-
video_mixer_release_device_manager(mixer);
if (param)
hr = IUnknown_QueryInterface((IUnknown *)param, &IID_IDirect3DDeviceManager9, (void **)&mixer->device_manager);
- LeaveCriticalSection(&mixer->cs);
-
break;
case MFT_MESSAGE_COMMAND_FLUSH:
-
- EnterCriticalSection(&mixer->cs);
video_mixer_flush_input(mixer);
- LeaveCriticalSection(&mixer->cs);
break;
case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING:
case MFT_MESSAGE_NOTIFY_END_STREAMING:
-
- EnterCriticalSection(&mixer->cs);
-
- if (!mixer->is_streaming)
+ if (mixer->is_streaming)
+ video_mixer_flush_input(mixer);
+ else
{
for (i = 0; i < mixer->input_count; ++i)
video_mixer_request_sample(mixer, i);
@@ -1160,8 +1153,6 @@ static HRESULT WINAPI video_mixer_transform_ProcessMessage(IMFTransform *iface,
mixer->is_streaming = message == MFT_MESSAGE_NOTIFY_BEGIN_STREAMING;
- LeaveCriticalSection(&mixer->cs);
-
break;
case MFT_MESSAGE_COMMAND_DRAIN:
@@ -1172,6 +1163,8 @@ static HRESULT WINAPI video_mixer_transform_ProcessMessage(IMFTransform *iface,
hr = E_NOTIMPL;
}
+ LeaveCriticalSection(&mixer->cs);
+
return hr;
}
diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c
index 57b64937b79..046a7e4db59 100644
--- a/dlls/evr/tests/evr.c
+++ b/dlls/evr/tests/evr.c
@@ -94,6 +94,15 @@ static IFilterGraph2 *create_graph(void)
return ret;
}
+#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
+static void _expect_ref(IUnknown *obj, ULONG ref, int line)
+{
+ ULONG rc;
+ IUnknown_AddRef(obj);
+ rc = IUnknown_Release(obj);
+ ok_(__FILE__,line)(rc == ref, "Unexpected refcount %d, expected %d.\n", rc, ref);
+}
+
static ULONG get_refcount(void *iface)
{
IUnknown *unknown = iface;
@@ -3061,6 +3070,117 @@ static void test_MFIsFormatYUV(void)
}
}
+static void test_mixer_render(void)
+{
+ IMFMediaType *video_type, *output_type;
+ IMFVideoMixerControl *mixer_control;
+ IDirect3DDeviceManager9 *manager;
+ IMFVideoProcessor *processor;
+ IDirect3DSurface9 *surface;
+ IDirect3DDevice9 *device;
+ IMFTransform *mixer;
+ IMFSample *sample;
+ DWORD status;
+ HWND window;
+ UINT token;
+ HRESULT hr;
+
+ window = create_window();
+ if (!(device = create_device(window)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ goto done;
+ }
+
+ hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
+ ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
+
+ hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoProcessor, (void **)&processor);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ /* Configure device and media types. */
+ hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
+ ok(hr == S_OK, "Failed to set a device, hr %#x.\n", hr);
+
+ hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ video_type = create_video_type(&MFVideoFormat_RGB32);
+
+ hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)64 << 32 | 64);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTransform_GetOutputAvailableType(mixer, 0, 0, &output_type);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTransform_SetOutputType(mixer, 0, output_type, 0);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ IMFMediaType_Release(output_type);
+ IMFMediaType_Release(video_type);
+
+ surface = create_surface(manager, 64, 64);
+ ok(!!surface, "Failed to create input surface.\n");
+
+ hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ EXPECT_REF(sample, 1);
+ hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ EXPECT_REF(sample, 2);
+
+ hr = IMFTransform_GetOutputStatus(mixer, &status);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(status == MFT_OUTPUT_STATUS_SAMPLE_READY, "Unexpected status %#x.\n", status);
+
+ /* FLUSH/END_STREAMING releases input */
+ hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_NOTIFY_END_STREAMING, 0);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ EXPECT_REF(sample, 1);
+
+ hr = IMFTransform_GetOutputStatus(mixer, &status);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(!status, "Unexpected status %#x.\n", status);
+
+ hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ EXPECT_REF(sample, 2);
+
+ hr = IMFTransform_GetOutputStatus(mixer, &status);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(status == MFT_OUTPUT_STATUS_SAMPLE_READY, "Unexpected status %#x.\n", status);
+
+ hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_COMMAND_FLUSH, 0);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ EXPECT_REF(sample, 1);
+
+ hr = IMFTransform_GetOutputStatus(mixer, &status);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(!status, "Unexpected status %#x.\n", status);
+
+ IMFSample_Release(sample);
+ IDirect3DSurface9_Release(surface);
+ IMFTransform_Release(mixer);
+
+ IDirect3DDevice9_Release(device);
+ IDirect3DDeviceManager9_Release(manager);
+
+done:
+ DestroyWindow(window);
+}
+
START_TEST(evr)
{
IMFVideoPresenter *presenter;
@@ -3099,6 +3219,7 @@ START_TEST(evr)
test_mixer_output_rectangle();
test_mixer_zorder();
test_mixer_samples();
+ test_mixer_render();
test_MFIsFormatYUV();
CoUninitialize();
--
2.33.0
More information about the wine-devel
mailing list