Nikolay Sivov : evr/mixer: Keep dxva device handle around.

Alexandre Julliard julliard at winehq.org
Wed Oct 21 15:15:13 CDT 2020


Module: wine
Branch: master
Commit: 35663e6a7fd9a1d73a3aad5129b8f59bc0923c82
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=35663e6a7fd9a1d73a3aad5129b8f59bc0923c82

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Oct 21 09:46:29 2020 +0300

evr/mixer: Keep dxva device handle around.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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);
 




More information about the wine-cvs mailing list