evr/mixer: Fill output surfaces when not streaming.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-10-22 14:02:46 +03:00 committed by Alexandre Julliard
parent d63ff3403b
commit 775daad7ef
2 changed files with 101 additions and 11 deletions

View File

@ -712,6 +712,13 @@ static HRESULT video_mixer_collect_output_types(struct video_mixer *mixer, const
return count ? S_OK : hr; 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) static HRESULT video_mixer_get_processor_service(struct video_mixer *mixer, IDirectXVideoProcessorService **service)
{ {
HRESULT hr; HRESULT hr;
@ -728,9 +735,7 @@ static HRESULT video_mixer_get_processor_service(struct video_mixer *mixer, IDir
&IID_IDirectXVideoProcessorService, (void **)service); &IID_IDirectXVideoProcessorService, (void **)service);
if (hr == DXVA2_E_NEW_VIDEO_DEVICE) if (hr == DXVA2_E_NEW_VIDEO_DEVICE)
{ {
IDirect3DDeviceManager9_CloseDeviceHandle(mixer->device_manager, mixer->device_handle); if (SUCCEEDED(hr = video_mixer_open_device_handle(mixer)))
mixer->device_handle = NULL;
if (SUCCEEDED(hr = IDirect3DDeviceManager9_OpenDeviceHandle(mixer->device_manager, &mixer->device_handle)))
continue; continue;
} }
break; break;
@ -1083,12 +1088,86 @@ static HRESULT WINAPI video_mixer_transform_ProcessInput(IMFTransform *iface, DW
return hr; return hr;
} }
static HRESULT WINAPI video_mixer_transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, static HRESULT video_mixer_get_sample_surface(IMFSample *sample, IDirect3DSurface9 **surface)
MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
{ {
FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); IMFMediaBuffer *buffer;
IMFGetService *gs;
HRESULT hr;
return E_NOTIMPL; 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 *buffers, DWORD *status)
{
struct video_mixer *mixer = impl_from_IMFTransform(iface);
IDirect3DSurface9 *surface;
IDirect3DDevice9 *device;
HRESULT hr;
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 = static const IMFTransformVtbl video_mixer_transform_vtbl =

View File

@ -2062,6 +2062,7 @@ static void test_mixer_samples(void)
{ {
IDirect3DDeviceManager9 *manager; IDirect3DDeviceManager9 *manager;
MFT_OUTPUT_DATA_BUFFER buffer; MFT_OUTPUT_DATA_BUFFER buffer;
IMFVideoProcessor *processor;
IDirect3DSurface9 *surface; IDirect3DSurface9 *surface;
IMFDesiredSample *desired; IMFDesiredSample *desired;
IDirect3DDevice9 *device; IDirect3DDevice9 *device;
@ -2086,6 +2087,9 @@ static void test_mixer_samples(void)
hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer); hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr); 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); hr = IMFTransform_GetInputStatus(mixer, 0, NULL);
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
@ -2147,7 +2151,6 @@ static void test_mixer_samples(void)
memset(&buffer, 0, sizeof(buffer)); memset(&buffer, 0, sizeof(buffer));
hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status); hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status);
todo_wine
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
/* It needs a sample with a backing surface. */ /* It needs a sample with a backing surface. */
@ -2156,7 +2159,6 @@ todo_wine
buffer.pSample = sample; buffer.pSample = sample;
hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status); hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status);
todo_wine
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
IMFSample_Release(sample); IMFSample_Release(sample);
@ -2175,17 +2177,25 @@ todo_wine
ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr); ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
color = get_surface_color(surface, 0, 0); color = get_surface_color(surface, 0, 0);
todo_wine
ok(color == D3DCOLOR_ARGB(0x10, 0xff, 0x00, 0x00), "Unexpected color %#x.\n", color); 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. */ /* Streaming is not started yet. Output is colored black, but only if desired timestamps were set. */
IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired, 100, 0); IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired, 100, 0);
hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status); hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status);
todo_wine
ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
color = get_surface_color(surface, 0, 0); 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); ok(!color, "Unexpected color %#x.\n", color);
IMFDesiredSample_Clear(desired); IMFDesiredSample_Clear(desired);
@ -2231,6 +2241,7 @@ todo_wine
IDirect3DSurface9_Release(surface); IDirect3DSurface9_Release(surface);
IMFVideoProcessor_Release(processor);
IMFTransform_Release(mixer); IMFTransform_Release(mixer);
IDirect3DDevice9_Release(device); IDirect3DDevice9_Release(device);