[PATCH 1/6] strmbase: Add a cached implementation of IDispatch and use it in IBasicVideo.

Zebediah Figura zfigura at codeweavers.com
Thu Jun 6 18:49:21 CDT 2019


From: Zebediah Figura <z.figura12 at gmail.com>

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/strmbase/dispatch.c | 49 +++++++++++++++++++++++++++++++
 dlls/strmbase/video.c    | 63 +++++++++++++++++++++++-----------------
 include/wine/strmbase.h  | 14 ++++++++-
 3 files changed, 98 insertions(+), 28 deletions(-)

diff --git a/dlls/strmbase/dispatch.c b/dlls/strmbase/dispatch.c
index e91b65a94a..1521471889 100644
--- a/dlls/strmbase/dispatch.c
+++ b/dlls/strmbase/dispatch.c
@@ -20,6 +20,55 @@
 
 #include "strmbase_private.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
+
+static ITypeLib *control_typelib;
+static ITypeInfo *control_typeinfo[last_tid];
+
+static REFIID control_tid_id[] =
+{
+    &IID_IBasicAudio,
+    &IID_IBasicVideo,
+    &IID_IMediaControl,
+    &IID_IMediaEvent,
+    &IID_IMediaPosition,
+    &IID_IVideoWindow,
+};
+
+HRESULT strmbase_get_typeinfo(enum strmbase_type_id tid, ITypeInfo **ret)
+{
+    HRESULT hr;
+
+    if (!control_typelib)
+    {
+        ITypeLib *typelib;
+
+        hr = LoadRegTypeLib(&LIBID_QuartzTypeLib, 1, 0, LOCALE_SYSTEM_DEFAULT, &typelib);
+        if (FAILED(hr))
+        {
+            ERR("Failed to load typelib, hr %#x.\n", hr);
+            return hr;
+        }
+        if (InterlockedCompareExchangePointer((void **)&control_typelib, typelib, NULL))
+            ITypeLib_Release(typelib);
+    }
+    if (!control_typeinfo[tid])
+    {
+        ITypeInfo *typeinfo;
+
+        hr = ITypeLib_GetTypeInfoOfGuid(control_typelib, control_tid_id[tid], &typeinfo);
+        if (FAILED(hr))
+        {
+            ERR("Failed to get type info for %s, hr %#x.\n", debugstr_guid(control_tid_id[tid]), hr);
+            return hr;
+        }
+        if (InterlockedCompareExchangePointer((void **)(control_typeinfo + tid), typeinfo, NULL))
+            ITypeInfo_Release(typeinfo);
+    }
+    ITypeInfo_AddRef(*ret = control_typeinfo[tid]);
+    return S_OK;
+}
+
 HRESULT WINAPI BaseDispatch_Init(BaseDispatch *This, REFIID riid)
 {
     ITypeLib *pTypeLib;
diff --git a/dlls/strmbase/video.c b/dlls/strmbase/video.c
index 2857932a05..440adc43a8 100644
--- a/dlls/strmbase/video.c
+++ b/dlls/strmbase/video.c
@@ -35,14 +35,12 @@ HRESULT WINAPI BaseControlVideo_Init(BaseControlVideo *pControlVideo, const IBas
     pControlVideo->pPin = pPin;
     pControlVideo->pFuncsTable = pFuncsTable;
 
-    BaseDispatch_Init(&pControlVideo->baseDispatch, &IID_IBasicVideo);
-
     return S_OK;
 }
 
 HRESULT WINAPI BaseControlVideo_Destroy(BaseControlVideo *pControlVideo)
 {
-    return BaseDispatch_Destroy(&pControlVideo->baseDispatch);
+    return S_OK;
 }
 
 static HRESULT BaseControlVideoImpl_CheckSourceRect(BaseControlVideo *This, RECT *pSourceRect)
@@ -72,40 +70,51 @@ static HRESULT BaseControlVideoImpl_CheckTargetRect(BaseControlVideo *This, RECT
     return S_OK;
 }
 
-HRESULT WINAPI BaseControlVideoImpl_GetTypeInfoCount(IBasicVideo *iface, UINT *pctinfo)
+HRESULT WINAPI BaseControlVideoImpl_GetTypeInfoCount(IBasicVideo *iface, UINT *count)
 {
-    BaseControlVideo *This = impl_from_IBasicVideo(iface);
-
-    return BaseDispatchImpl_GetTypeInfoCount(&This->baseDispatch, pctinfo);
+    TRACE("iface %p, count %p.\n", iface, count);
+    *count = 1;
+    return S_OK;
 }
 
-HRESULT WINAPI BaseControlVideoImpl_GetTypeInfo(IBasicVideo *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
+HRESULT WINAPI BaseControlVideoImpl_GetTypeInfo(IBasicVideo *iface, UINT index,
+        LCID lcid, ITypeInfo **typeinfo)
 {
-    BaseControlVideo *This = impl_from_IBasicVideo(iface);
-
-    return BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, &IID_NULL, iTInfo, lcid, ppTInfo);
+    TRACE("iface %p, index %u, lcid %#x, typeinfo %p.\n", iface, index, lcid, typeinfo);
+    return strmbase_get_typeinfo(IBasicVideo_tid, typeinfo);
 }
 
-HRESULT WINAPI BaseControlVideoImpl_GetIDsOfNames(IBasicVideo *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
+HRESULT WINAPI BaseControlVideoImpl_GetIDsOfNames(IBasicVideo *iface, REFIID iid,
+        LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
 {
-    BaseControlVideo *This = impl_from_IBasicVideo(iface);
-
-    return BaseDispatchImpl_GetIDsOfNames(&This->baseDispatch, riid, rgszNames, cNames, lcid, rgDispId);
-}
-
-HRESULT WINAPI BaseControlVideoImpl_Invoke(IBasicVideo *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr)
-{
-    BaseControlVideo *This = impl_from_IBasicVideo(iface);
-    ITypeInfo *pTypeInfo;
+    ITypeInfo *typeinfo;
     HRESULT hr;
 
-    hr = BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, riid, 1, lcid, &pTypeInfo);
-    if (SUCCEEDED(hr))
-    {
-        hr = ITypeInfo_Invoke(pTypeInfo, &This->IBasicVideo_iface, dispIdMember, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
-        ITypeInfo_Release(pTypeInfo);
-    }
+    TRACE("iface %p, iid %s, names %p, count %u, lcid %#x, ids %p.\n",
+            iface, debugstr_guid(iid), names, count, lcid, ids);
 
+    if (SUCCEEDED(hr = strmbase_get_typeinfo(IBasicVideo_tid, &typeinfo)))
+    {
+        hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, ids);
+        ITypeInfo_Release(typeinfo);
+    }
+    return hr;
+}
+
+HRESULT WINAPI BaseControlVideoImpl_Invoke(IBasicVideo *iface, DISPID id, REFIID iid, LCID lcid,
+        WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *error_arg)
+{
+    ITypeInfo *typeinfo;
+    HRESULT hr;
+
+    TRACE("iface %p, id %d, iid %s, lcid %#x, flags %#x, params %p, result %p, excepinfo %p, error_arg %p.\n",
+            iface, id, debugstr_guid(iid), lcid, flags, params, result, excepinfo, error_arg);
+
+    if (SUCCEEDED(hr = strmbase_get_typeinfo(IBasicVideo_tid, &typeinfo)))
+    {
+        hr = ITypeInfo_Invoke(typeinfo, iface, id, flags, params, result, excepinfo, error_arg);
+        ITypeInfo_Release(typeinfo);
+    }
     return hr;
 }
 
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 56560ed02b..0cbb7c3b78 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -399,6 +399,19 @@ RECT WINAPI BaseWindowImpl_GetDefaultRect(BaseWindow *This);
 LRESULT WINAPI BaseWindowImpl_OnReceiveMessage(BaseWindow *This, HWND hwnd, INT uMsg, WPARAM wParam, LPARAM lParam);
 BOOL WINAPI BaseWindowImpl_OnSize(BaseWindow *This, LONG Height, LONG Width);
 
+enum strmbase_type_id
+{
+    IBasicAudio_tid,
+    IBasicVideo_tid,
+    IMediaControl_tid,
+    IMediaEvent_tid,
+    IMediaPosition_tid,
+    IVideoWindow_tid,
+    last_tid
+};
+
+HRESULT strmbase_get_typeinfo(enum strmbase_type_id tid, ITypeInfo **typeinfo);
+
 typedef struct{
     ITypeInfo *pTypeInfo;
 } BaseDispatch;
@@ -473,7 +486,6 @@ HRESULT WINAPI BaseControlWindowImpl_IsCursorHidden(IVideoWindow *iface, LONG *C
 typedef struct tagBaseControlVideo
 {
 	IBasicVideo IBasicVideo_iface;
-	BaseDispatch baseDispatch;
 
 	BaseFilter* pFilter;
 	CRITICAL_SECTION* pInterfaceLock;
-- 
2.20.1




More information about the wine-devel mailing list