[PATCH 1/5] evr/mixer: Keep dxva device handle around.
Nikolay Sivov
nsivov at codeweavers.com
Tue Oct 20 04:32:39 CDT 2020
Signed-off-by: Nikolay Sivov <nsivov at 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);
--
2.28.0
More information about the wine-devel
mailing list