Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dxva2/main.c | 2 +- dlls/dxva2/tests/dxva2.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/dxva2/main.c b/dlls/dxva2/main.c index 6262531c7d1..83c4723a7dc 100644 --- a/dlls/dxva2/main.c +++ b/dlls/dxva2/main.c @@ -562,7 +562,7 @@ static HRESULT WINAPI device_manager_OpenDeviceHandle(IDirect3DDeviceManager9 *i
static HRESULT device_manager_get_handle_index(struct device_manager *manager, HANDLE hdevice, size_t *idx) { - if (hdevice > ULongToHandle(manager->count)) + if (!hdevice || hdevice > ULongToHandle(manager->count)) return E_HANDLE; *idx = (ULONG_PTR)hdevice - 1; return S_OK; diff --git a/dlls/dxva2/tests/dxva2.c b/dlls/dxva2/tests/dxva2.c index f617bf74079..a49635e7596 100644 --- a/dlls/dxva2/tests/dxva2.c +++ b/dlls/dxva2/tests/dxva2.c @@ -115,6 +115,9 @@ static void test_device_manager(void) hr = IDirect3DDeviceManager9_LockDevice(manager, 0, &device2, FALSE); ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
+ hr = IDirect3DDeviceManager9_CloseDeviceHandle(manager, 0); + ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr); + /* Invalid token. */ hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token + 1); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); @@ -123,9 +126,13 @@ static void test_device_manager(void) ok(hr == S_OK, "Unexpected hr %#x.\n", hr); refcount = get_refcount(device);
+ hr = IDirect3DDeviceManager9_CloseDeviceHandle(manager, 0); + ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr); + handle1 = NULL; hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle1); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!!handle1, "Unexpected handle value.\n");
refcount2 = get_refcount(device); ok(refcount2 == refcount, "Unexpected refcount %d.\n", refcount); @@ -152,6 +159,9 @@ static void test_device_manager(void) hr = IDirect3DDeviceManager9_TestDevice(manager, handle1); ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
+ hr = IDirect3DDeviceManager9_TestDevice(manager, 0); + ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr); + handle = NULL; hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/mixer.c | 90 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 29 deletions(-)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index fd7596eeadf..42e0ca42f91 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -81,12 +81,14 @@ struct video_mixer unsigned int input_count; struct output_stream output;
- COLORREF bkgnd_color; IDirect3DDeviceManager9 *device_manager; + HANDLE device_handle; + IMediaEventSink *event_sink; IMFAttributes *attributes; IMFAttributes *internal_attributes; unsigned int mixing_flags; + COLORREF bkgnd_color; LONGLONG lower_bound; LONGLONG upper_bound; CRITICAL_SECTION cs; @@ -266,6 +268,17 @@ static ULONG WINAPI video_mixer_inner_AddRef(IUnknown *iface) return refcount; }
+static void video_mixer_release_device_manager(struct video_mixer *mixer) +{ + if (mixer->device_manager) + { + IDirect3DDeviceManager9_CloseDeviceHandle(mixer->device_manager, mixer->device_handle); + IDirect3DDeviceManager9_Release(mixer->device_manager); + } + mixer->device_handle = NULL; + mixer->device_manager = NULL; +} + static ULONG WINAPI video_mixer_inner_Release(IUnknown *iface) { struct video_mixer *mixer = impl_from_IUnknown(iface); @@ -282,8 +295,7 @@ static ULONG WINAPI video_mixer_inner_Release(IUnknown *iface) IMFAttributes_Release(mixer->inputs[i].attributes); } video_mixer_clear_types(mixer); - if (mixer->device_manager) - IDirect3DDeviceManager9_Release(mixer->device_manager); + video_mixer_release_device_manager(mixer); if (mixer->attributes) IMFAttributes_Release(mixer->attributes); if (mixer->internal_attributes) @@ -695,6 +707,33 @@ static HRESULT video_mixer_collect_output_types(struct video_mixer *mixer, const return count ? S_OK : hr; }
+static HRESULT video_mixer_get_processor_service(struct video_mixer *mixer, IDirectXVideoProcessorService **service) +{ + HRESULT hr; + + if (!mixer->device_handle) + { + if (FAILED(hr = IDirect3DDeviceManager9_OpenDeviceHandle(mixer->device_manager, &mixer->device_handle))) + return hr; + } + + for (;;) + { + hr = IDirect3DDeviceManager9_GetVideoService(mixer->device_manager, mixer->device_handle, + &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))) + continue; + } + break; + } + + return hr; +} + static HRESULT WINAPI video_mixer_transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *media_type, DWORD flags) { struct video_mixer *mixer = impl_from_IMFTransform(iface); @@ -702,7 +741,6 @@ static HRESULT WINAPI video_mixer_transform_SetInputType(IMFTransform *iface, DW DXVA2_VideoDesc video_desc; HRESULT hr = E_NOTIMPL; unsigned int count; - HANDLE handle; GUID *guids;
TRACE("%p, %u, %p, %#x.\n", iface, id, media_type, flags); @@ -716,37 +754,33 @@ static HRESULT WINAPI video_mixer_transform_SetInputType(IMFTransform *iface, DW hr = MF_E_NOT_INITIALIZED; else { - if (SUCCEEDED(hr = IDirect3DDeviceManager9_OpenDeviceHandle(mixer->device_manager, &handle))) + if (SUCCEEDED(hr = video_mixer_get_processor_service(mixer, &service))) { - if (SUCCEEDED(hr = IDirect3DDeviceManager9_GetVideoService(mixer->device_manager, handle, - &IID_IDirectXVideoProcessorService, (void **)&service))) + if (SUCCEEDED(hr = video_mixer_init_dxva_videodesc(media_type, &video_desc))) { - if (SUCCEEDED(hr = video_mixer_init_dxva_videodesc(media_type, &video_desc))) + if (!id) { - if (!id) + if (SUCCEEDED(hr = IDirectXVideoProcessorService_GetVideoProcessorDeviceGuids(service, &video_desc, + &count, &guids))) { - if (SUCCEEDED(hr = IDirectXVideoProcessorService_GetVideoProcessorDeviceGuids(service, &video_desc, - &count, &guids))) + if (SUCCEEDED(hr = video_mixer_collect_output_types(mixer, &video_desc, service, count, + guids, flags)) && !(flags & MFT_SET_TYPE_TEST_ONLY)) { - if (SUCCEEDED(hr = video_mixer_collect_output_types(mixer, &video_desc, service, count, - guids, flags)) && !(flags & MFT_SET_TYPE_TEST_ONLY)) - { - if (mixer->inputs[0].media_type) - IMFMediaType_Release(mixer->inputs[0].media_type); - mixer->inputs[0].media_type = media_type; - IMFMediaType_AddRef(mixer->inputs[0].media_type); - } - CoTaskMemFree(guids); + if (mixer->inputs[0].media_type) + IMFMediaType_Release(mixer->inputs[0].media_type); + mixer->inputs[0].media_type = media_type; + IMFMediaType_AddRef(mixer->inputs[0].media_type); } + CoTaskMemFree(guids); } - else - { - FIXME("Unimplemented for substreams.\n"); - hr = E_NOTIMPL; - } + } + else + { + FIXME("Unimplemented for substreams.\n"); + hr = E_NOTIMPL; } } - IDirect3DDeviceManager9_CloseDeviceHandle(mixer->device_manager, handle); + IDirectXVideoProcessorService_Release(service); } }
@@ -897,9 +931,7 @@ static HRESULT WINAPI video_mixer_transform_ProcessMessage(IMFTransform *iface,
EnterCriticalSection(&mixer->cs);
- if (mixer->device_manager) - IDirect3DDeviceManager9_Release(mixer->device_manager); - mixer->device_manager = NULL; + video_mixer_release_device_manager(mixer); if (param) hr = IUnknown_QueryInterface((IUnknown *)param, &IID_IDirect3DDeviceManager9, (void **)&mixer->device_manager);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/mixer.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index 42e0ca42f91..1b77afac5b2 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -82,6 +82,7 @@ struct video_mixer struct output_stream output;
IDirect3DDeviceManager9 *device_manager; + IDirectXVideoProcessor *processor; HANDLE device_handle;
IMediaEventSink *event_sink; @@ -270,6 +271,8 @@ static ULONG WINAPI video_mixer_inner_AddRef(IUnknown *iface)
static void video_mixer_release_device_manager(struct video_mixer *mixer) { + if (mixer->processor) + IDirectXVideoProcessor_Release(mixer->processor); if (mixer->device_manager) { IDirect3DDeviceManager9_CloseDeviceHandle(mixer->device_manager, mixer->device_handle); @@ -277,6 +280,7 @@ static void video_mixer_release_device_manager(struct video_mixer *mixer) } mixer->device_handle = NULL; mixer->device_manager = NULL; + mixer->processor = NULL; }
static ULONG WINAPI video_mixer_inner_Release(IUnknown *iface) @@ -819,10 +823,33 @@ static HRESULT WINAPI video_mixer_transform_SetOutputType(IMFTransform *iface, D
if (SUCCEEDED(hr) && !(flags & MFT_SET_TYPE_TEST_ONLY)) { - if (mixer->output.media_type) - IMFMediaType_Release(mixer->output.media_type); - mixer->output.media_type = type; - IMFMediaType_AddRef(mixer->output.media_type); + IDirectXVideoProcessorService *service; + + if (SUCCEEDED(hr = video_mixer_get_processor_service(mixer, &service))) + { + DXVA2_VideoDesc video_desc; + GUID subtype = { 0 }; + D3DFORMAT rt_format; + + if (mixer->processor) + IDirectXVideoProcessor_Release(mixer->processor); + mixer->processor = NULL; + + video_mixer_init_dxva_videodesc(mixer->inputs[0].media_type, &video_desc); + IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype); + rt_format = subtype.Data1; + + if (SUCCEEDED(hr = IDirectXVideoProcessorService_CreateVideoProcessor(service, &mixer->output.rt_formats[i].device, + &video_desc, rt_format, MAX_MIXER_INPUT_STREAMS, &mixer->processor))) + { + if (mixer->output.media_type) + IMFMediaType_Release(mixer->output.media_type); + mixer->output.media_type = type; + IMFMediaType_AddRef(mixer->output.media_type); + } + + IDirectXVideoProcessorService_Release(service); + } }
LeaveCriticalSection(&mixer->cs);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/mixer.c | 4 ++++ dlls/evr/tests/evr.c | 3 +++ 2 files changed, 7 insertions(+)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index 1b77afac5b2..28361255fe1 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -965,6 +965,10 @@ static HRESULT WINAPI video_mixer_transform_ProcessMessage(IMFTransform *iface, LeaveCriticalSection(&mixer->cs);
break; + + case MFT_MESSAGE_COMMAND_DRAIN: + break; + default: WARN("Message not handled %d.\n", message); hr = E_NOTIMPL; diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 182280d0a39..d71a63ff602 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -2171,6 +2171,9 @@ todo_wine hr = IMFTransform_ProcessInput(mixer, 5, sample, 0); ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
+ hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_COMMAND_DRAIN, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IMFSample_Release(sample);
IDirect3DSurface9_Release(surface);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/mixer.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index 28361255fe1..5ea1b9aa22b 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -949,6 +949,7 @@ static HRESULT WINAPI video_mixer_transform_ProcessMessage(IMFTransform *iface, { struct video_mixer *mixer = impl_from_IMFTransform(iface); HRESULT hr = S_OK; + unsigned int i;
TRACE("%p, %u, %#lx.\n", iface, message, param);
@@ -966,6 +967,23 @@ static HRESULT WINAPI video_mixer_transform_ProcessMessage(IMFTransform *iface,
break;
+ case MFT_MESSAGE_COMMAND_FLUSH: + + EnterCriticalSection(&mixer->cs); + + for (i = 0; i < mixer->input_count; ++i) + { + if (mixer->inputs[i].sample) + { + IMFSample_Release(mixer->inputs[i].sample); + mixer->inputs[i].sample = NULL; + } + } + + LeaveCriticalSection(&mixer->cs); + + break; + case MFT_MESSAGE_COMMAND_DRAIN: break;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/mixer.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index 5ea1b9aa22b..55acf179bdc 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -89,6 +89,7 @@ struct video_mixer IMFAttributes *attributes; IMFAttributes *internal_attributes; unsigned int mixing_flags; + unsigned int is_streaming; COLORREF bkgnd_color; LONGLONG lower_bound; LONGLONG upper_bound; @@ -984,6 +985,17 @@ static HRESULT WINAPI video_mixer_transform_ProcessMessage(IMFTransform *iface,
break;
+ case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: + case MFT_MESSAGE_NOTIFY_END_STREAMING: + + EnterCriticalSection(&mixer->cs); + + mixer->is_streaming = message == MFT_MESSAGE_NOTIFY_BEGIN_STREAMING; + + LeaveCriticalSection(&mixer->cs); + + break; + case MFT_MESSAGE_COMMAND_DRAIN: break;
@@ -1016,6 +1028,7 @@ static HRESULT WINAPI video_mixer_transform_ProcessInput(IMFTransform *iface, DW hr = MF_E_NOTACCEPTING; else { + mixer->is_streaming = 1; input->sample = sample; IMFSample_AddRef(input->sample); }