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); }
Nikolay Sivov nsivov@codeweavers.com writes:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/evr/mixer.c | 90 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 29 deletions(-)
This is breaking the tests here:
tools/runtest -q -P wine -T . -M mf.dll -p dlls/mf/tests/mf_test.exe mf && touch dlls/mf/tests/mf.ok wine: Unhandled page fault on read access to FFFFFFF8 at address 712C1A82 (thread 0024), starting debugger... Unhandled exception: page fault on read access to 0xfffffff8 in 32-bit code (0x712c1a82). Register dump: CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b EIP:712c1a82 ESP:0068fa10 EBP:0068fa58 EFLAGS:00210282( R- -- I S - - - ) EAX:fffffff8 EBX:01663518 ECX:ffffffff EDX:fffffff8 ESI:00000000 EDI:0166353c Stack dump: 0x0068fa10: 0166353c 00000000 00110094 00000000 0x0068fa20: 01664f38 01660000 0068fa48 6825a467 0x0068fa30: 01664f38 00000000 01662cc0 00000000 0x0068fa40: 01664f30 00000000 0068fa78 002712f0 0x0068fa50: 0027134c 002712f0 0068fa78 65582215 0x0068fa60: 01663518 00000000 00000000 00271318 Backtrace: =>0 0x712c1a82 device_manager_CloseDeviceHandle+0x42(hdevice=0x0(nil)) [Z:\home\julliard\wine\wine\dlls\dxva2\main.c:582] in dxva2 (0x0068fa58) 1 0x65582215 video_mixer_release_device_manager+0x24(mixer=0x2712f0) [Z:\home\julliard\wine\wine\include\dxva2api.h:669] in evr (0x0068fa78) 2 0x655843d8 video_mixer_inner_Release+0x77() [Z:\home\julliard\wine\wine\dlls\evr\mixer.c:298] in evr (0x0068fac8) 3 0x6558853a video_presenter_clear_container+0x29(presenter=0x16646d8) [Z:\home\julliard\wine\wine\include\mftransform.h:430] in evr (0x0068fae8) 4 0x65588fe2 video_presenter_inner_Release+0x71() [Z:\home\julliard\wine\wine\dlls\evr\presenter.c:237] in evr (0x0068fb28) 5 0x71143b07 video_renderer_initialize+0x36(renderer=0x1662808, mixer=0x271600, presenter=0x16a9b60) [Z:\home\julliard\wine\wine\include\evr.h:243] in mf (0x0068fb88) 6 0x7114454e video_renderer_InitializeRenderer+0x17d(mixer=<is not available>, presenter=<is not available>) [Z:\home\julliard\wine\wine\dlls\mf\evr.c:1242] in mf (0x0068fbe8) 7 0x0040b584 test_evr+0xb3() [Z:\home\julliard\wine\wine\include\evr.h:520] in mf_test (0x0068fca8) 8 0x00413e98 func_mf+0x25c7() [Z:\home\julliard\wine\wine\dlls\mf\tests\mf.c:4025] in mf_test (0x0068fdc8) 9 0x004164b2 run_test+0xe1(name=<is not available>) [Z:\home\julliard\wine\wine\include\wine\test.h:569] in mf_test (0x0068fe28) 10 0x00417ea3 main+0x182(argv=<is not available>) [Z:\home\julliard\wine\wine\include\wine\test.h:659] in mf_test (0x0068fed8) 11 0x004172d6 mainCRTStartup+0x75() [Z:\home\julliard\wine\wine\dlls\msvcrt\crt_main.c:62] in mf_test (0x0068ff28) 12 0x7b62c78e BaseThreadInitThunk+0xd(unknown=<is not available>, entry=<is not available>) [Z:\home\julliard\wine\wine\dlls\kernel32\thread.c:60] in kernel32 (0x0068ff48) 13 0x7bc54fd7 RtlSleepConditionVariableSRW+0x196(lock=<is not available>, timeout=<is not available>, flags=<is not available>) [Z:\home\julliard\wine\wine\dlls\ntdll\sync.c:556] in ntdll (0x0068ff5c) 14 0x7bc55200 call_thread_func+0xaf(arg=0x7ffde000) [Z:\home\julliard\wine\wine\dlls\ntdll\thread.c:134] in ntdll (0x0068ffec) 0x712c1a82 device_manager_CloseDeviceHandle+0x42 [Z:\home\julliard\wine\wine\dlls\dxva2\main.c:582] in dxva2: testb $0x1,0x0(%eax) 582 if (manager->handles[idx].flags & HANDLE_FLAG_OPEN)