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:
parent
d63ff3403b
commit
775daad7ef
|
@ -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 =
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue