Nikolay Sivov : evr/mixer: Fill output surfaces when not streaming.
Alexandre Julliard
julliard at winehq.org
Thu Oct 22 15:27:31 CDT 2020
Module: wine
Branch: master
Commit: 775daad7efcd272a35dc01178b18d701d0924e89
URL: https://source.winehq.org/git/wine.git/?a=commit;h=775daad7efcd272a35dc01178b18d701d0924e89
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Thu Oct 22 14:02:46 2020 +0300
evr/mixer: Fill output surfaces when not streaming.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/evr/mixer.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++----
dlls/evr/tests/evr.c | 19 ++++++++---
2 files changed, 100 insertions(+), 10 deletions(-)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c
index 2c2fda51cd1..b4bf1ed0967 100644
--- a/dlls/evr/mixer.c
+++ b/dlls/evr/mixer.c
@@ -712,6 +712,13 @@ static HRESULT video_mixer_collect_output_types(struct video_mixer *mixer, const
return count ? S_OK : hr;
}
+static HRESULT video_mixer_open_device_handle(struct video_mixer *mixer)
+{
+ IDirect3DDeviceManager9_CloseDeviceHandle(mixer->device_manager, mixer->device_handle);
+ mixer->device_handle = NULL;
+ return IDirect3DDeviceManager9_OpenDeviceHandle(mixer->device_manager, &mixer->device_handle);
+}
+
static HRESULT video_mixer_get_processor_service(struct video_mixer *mixer, IDirectXVideoProcessorService **service)
{
HRESULT hr;
@@ -728,9 +735,7 @@ static HRESULT video_mixer_get_processor_service(struct video_mixer *mixer, IDir
&IID_IDirectXVideoProcessorService, (void **)service);
if (hr == DXVA2_E_NEW_VIDEO_DEVICE)
{
- IDirect3DDeviceManager9_CloseDeviceHandle(mixer->device_manager, mixer->device_handle);
- mixer->device_handle = NULL;
- if (SUCCEEDED(hr = IDirect3DDeviceManager9_OpenDeviceHandle(mixer->device_manager, &mixer->device_handle)))
+ if (SUCCEEDED(hr = video_mixer_open_device_handle(mixer)))
continue;
}
break;
@@ -1083,12 +1088,86 @@ static HRESULT WINAPI video_mixer_transform_ProcessInput(IMFTransform *iface, DW
return hr;
}
+static HRESULT video_mixer_get_sample_surface(IMFSample *sample, IDirect3DSurface9 **surface)
+{
+ IMFMediaBuffer *buffer;
+ IMFGetService *gs;
+ HRESULT hr;
+
+ if (FAILED(hr = IMFSample_GetBufferByIndex(sample, 0, &buffer)))
+ return hr;
+
+ hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
+ IMFMediaBuffer_Release(buffer);
+ if (FAILED(hr))
+ return hr;
+
+ hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)surface);
+ IMFGetService_Release(gs);
+ return hr;
+}
+
+static HRESULT video_mixer_get_d3d_device(struct video_mixer *mixer, IDirect3DDevice9 **device)
+{
+ HRESULT hr;
+
+ for (;;)
+ {
+ hr = IDirect3DDeviceManager9_LockDevice(mixer->device_manager, mixer->device_handle,
+ device, TRUE);
+ if (hr == DXVA2_E_NEW_VIDEO_DEVICE)
+ {
+ if (SUCCEEDED(hr = video_mixer_open_device_handle(mixer)))
+ continue;
+ }
+ break;
+ }
+
+ return hr;
+}
+
static HRESULT WINAPI video_mixer_transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
- MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
+ MFT_OUTPUT_DATA_BUFFER *buffers, DWORD *status)
{
- FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
+ struct video_mixer *mixer = impl_from_IMFTransform(iface);
+ IDirect3DSurface9 *surface;
+ IDirect3DDevice9 *device;
+ HRESULT hr;
- return E_NOTIMPL;
+ TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, buffers, status);
+
+ if (!buffers || !count || !buffers->pSample)
+ return E_INVALIDARG;
+
+ if (count > 1)
+ FIXME("Multiple buffers are not handled.\n");
+
+ *status = 0;
+
+ EnterCriticalSection(&mixer->cs);
+
+ if (SUCCEEDED(hr = video_mixer_get_sample_surface(buffers->pSample, &surface)))
+ {
+ if (mixer->is_streaming)
+ {
+ FIXME("Streaming state is not handled.\n");
+ hr = E_NOTIMPL;
+ }
+ else
+ {
+ if (SUCCEEDED(hr = video_mixer_get_d3d_device(mixer, &device)))
+ {
+ IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
+ IDirect3DDeviceManager9_UnlockDevice(mixer->device_manager, mixer->device_handle, FALSE);
+ IDirect3DDevice9_Release(device);
+ }
+ }
+ IDirect3DSurface9_Release(surface);
+ }
+
+ LeaveCriticalSection(&mixer->cs);
+
+ return hr;
}
static const IMFTransformVtbl video_mixer_transform_vtbl =
diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c
index 7cf127d4d8c..fc74a11496b 100644
--- a/dlls/evr/tests/evr.c
+++ b/dlls/evr/tests/evr.c
@@ -2062,6 +2062,7 @@ static void test_mixer_samples(void)
{
IDirect3DDeviceManager9 *manager;
MFT_OUTPUT_DATA_BUFFER buffer;
+ IMFVideoProcessor *processor;
IDirect3DSurface9 *surface;
IMFDesiredSample *desired;
IDirect3DDevice9 *device;
@@ -2086,6 +2087,9 @@ static void test_mixer_samples(void)
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_GetInputStatus(mixer, 0, NULL);
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
@@ -2147,7 +2151,6 @@ static void test_mixer_samples(void)
memset(&buffer, 0, sizeof(buffer));
hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status);
-todo_wine
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
/* It needs a sample with a backing surface. */
@@ -2156,7 +2159,6 @@ todo_wine
buffer.pSample = sample;
hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status);
-todo_wine
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
IMFSample_Release(sample);
@@ -2175,17 +2177,25 @@ todo_wine
ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
color = get_surface_color(surface, 0, 0);
+todo_wine
ok(color == D3DCOLOR_ARGB(0x10, 0xff, 0x00, 0x00), "Unexpected color %#x.\n", color);
/* Streaming is not started yet. Output is colored black, but only if desired timestamps were set. */
IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired, 100, 0);
hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status);
-todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
color = get_surface_color(surface, 0, 0);
-todo_wine
+ ok(!color, "Unexpected color %#x.\n", color);
+
+ hr = IMFVideoProcessor_SetBackgroundColor(processor, RGB(0, 0, 255));
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ color = get_surface_color(surface, 0, 0);
ok(!color, "Unexpected color %#x.\n", color);
IMFDesiredSample_Clear(desired);
@@ -2231,6 +2241,7 @@ todo_wine
IDirect3DSurface9_Release(surface);
+ IMFVideoProcessor_Release(processor);
IMFTransform_Release(mixer);
IDirect3DDevice9_Release(device);
More information about the wine-cvs
mailing list