[PATCH 3/7] strmbase: Separate the seeking passthrough object from its implementation.

Zebediah Figura z.figura12 at gmail.com
Thu Mar 12 21:34:08 CDT 2020


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/strmbase/pospass.c | 275 +++++++++++++++++++++-------------------
 1 file changed, 147 insertions(+), 128 deletions(-)

diff --git a/dlls/strmbase/pospass.c b/dlls/strmbase/pospass.c
index 6920b378650..c5be17ec62b 100644
--- a/dlls/strmbase/pospass.c
+++ b/dlls/strmbase/pospass.c
@@ -24,16 +24,11 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
 
-static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl;
-static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl;
-
 typedef struct PassThruImpl {
-    IUnknown  IUnknown_inner;
     ISeekingPassThru ISeekingPassThru_iface;
     IMediaSeeking IMediaSeeking_iface;
     IMediaPosition IMediaPosition_iface;
 
-    LONG ref;
     IUnknown * outer_unk;
     IPin * pin;
     BOOL renderer;
@@ -42,11 +37,6 @@ typedef struct PassThruImpl {
     REFERENCE_TIME time_earliest;
 } PassThruImpl;
 
-static inline PassThruImpl *impl_from_IUnknown_inner(IUnknown *iface)
-{
-    return CONTAINING_RECORD(iface, PassThruImpl, IUnknown_inner);
-}
-
 static inline PassThruImpl *impl_from_ISeekingPassThru(ISeekingPassThru *iface)
 {
     return CONTAINING_RECORD(iface, PassThruImpl, ISeekingPassThru_iface);
@@ -62,66 +52,6 @@ static inline PassThruImpl *impl_from_IMediaPosition(IMediaPosition *iface)
     return CONTAINING_RECORD(iface, PassThruImpl, IMediaPosition_iface);
 }
 
-static HRESULT WINAPI SeekInner_QueryInterface(IUnknown * iface,
-					  REFIID riid,
-					  LPVOID *ppvObj) {
-    PassThruImpl *This = impl_from_IUnknown_inner(iface);
-    TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObj);
-
-    if (IsEqualGUID(&IID_IUnknown, riid))
-    {
-        *ppvObj = &(This->IUnknown_inner);
-        TRACE("   returning IUnknown interface (%p)\n", *ppvObj);
-    } else if (IsEqualGUID(&IID_ISeekingPassThru, riid)) {
-        *ppvObj = &(This->ISeekingPassThru_iface);
-        TRACE("   returning ISeekingPassThru interface (%p)\n", *ppvObj);
-    } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) {
-        *ppvObj = &(This->IMediaSeeking_iface);
-        TRACE("   returning IMediaSeeking interface (%p)\n", *ppvObj);
-    } else if (IsEqualGUID(&IID_IMediaPosition, riid)) {
-        *ppvObj = &(This->IMediaPosition_iface);
-        TRACE("   returning IMediaPosition interface (%p)\n", *ppvObj);
-    } else {
-        *ppvObj = NULL;
-        FIXME("unknown interface %s\n", debugstr_guid(riid));
-        return E_NOINTERFACE;
-    }
-
-    IUnknown_AddRef((IUnknown *)(*ppvObj));
-    return S_OK;
-}
-
-static ULONG WINAPI SeekInner_AddRef(IUnknown * iface) {
-    PassThruImpl *This = impl_from_IUnknown_inner(iface);
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p)->(): new ref = %d\n", This, ref);
-
-    return ref;
-}
-
-static ULONG WINAPI SeekInner_Release(IUnknown * iface) {
-    PassThruImpl *This = impl_from_IUnknown_inner(iface);
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p)->(): new ref = %d\n", This, ref);
-
-    if (ref == 0)
-    {
-        This->time_cs.DebugInfo->Spare[0] = 0;
-        DeleteCriticalSection(&This->time_cs);
-        CoTaskMemFree(This);
-    }
-    return ref;
-}
-
-static const IUnknownVtbl IInner_VTable =
-{
-    SeekInner_QueryInterface,
-    SeekInner_AddRef,
-    SeekInner_Release
-};
-
 static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID iid, void **out)
 {
     PassThruImpl *passthrough = impl_from_ISeekingPassThru(iface);
@@ -182,29 +112,6 @@ HRESULT WINAPI CreatePosPassThru(IUnknown* pUnkOuter, BOOL bRenderer, IPin *pPin
     return hr;
 }
 
-HRESULT WINAPI PosPassThru_Construct(IUnknown *pUnkOuter, LPVOID *ppPassThru)
-{
-    PassThruImpl *fimpl;
-
-    TRACE("(%p,%p)\n", pUnkOuter, ppPassThru);
-
-    *ppPassThru = fimpl = CoTaskMemAlloc(sizeof(*fimpl));
-    if (!fimpl)
-        return E_OUTOFMEMORY;
-
-    fimpl->outer_unk = pUnkOuter ? pUnkOuter : &fimpl->IUnknown_inner;
-    fimpl->IUnknown_inner.lpVtbl = &IInner_VTable;
-    fimpl->ISeekingPassThru_iface.lpVtbl = &ISeekingPassThru_Vtbl;
-    fimpl->IMediaSeeking_iface.lpVtbl = &IMediaSeekingPassThru_Vtbl;
-    fimpl->IMediaPosition_iface.lpVtbl = &IMediaPositionPassThru_Vtbl;
-    fimpl->ref = 1;
-    fimpl->pin = NULL;
-    fimpl->timevalid = FALSE;
-    InitializeCriticalSection(&fimpl->time_cs);
-    fimpl->time_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PassThruImpl.time_cs");
-    return S_OK;
-}
-
 static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out)
 {
     PassThruImpl *passthrough = impl_from_IMediaSeeking(iface);
@@ -523,41 +430,6 @@ static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LON
     return hr;
 }
 
-HRESULT WINAPI RendererPosPassThru_RegisterMediaTime(IUnknown *iface, REFERENCE_TIME start)
-{
-    PassThruImpl *This = impl_from_IUnknown_inner(iface);
-    EnterCriticalSection(&This->time_cs);
-    This->time_earliest = start;
-    This->timevalid = TRUE;
-    LeaveCriticalSection(&This->time_cs);
-    return S_OK;
-}
-
-HRESULT WINAPI RendererPosPassThru_ResetMediaTime(IUnknown *iface)
-{
-    PassThruImpl *This = impl_from_IUnknown_inner(iface);
-    EnterCriticalSection(&This->time_cs);
-    This->timevalid = FALSE;
-    LeaveCriticalSection(&This->time_cs);
-    return S_OK;
-}
-
-HRESULT WINAPI RendererPosPassThru_EOS(IUnknown *iface)
-{
-    PassThruImpl *This = impl_from_IUnknown_inner(iface);
-    REFERENCE_TIME time;
-    HRESULT hr;
-    hr = IMediaSeeking_GetStopPosition(&This->IMediaSeeking_iface, &time);
-    EnterCriticalSection(&This->time_cs);
-    if (SUCCEEDED(hr)) {
-        This->timevalid = TRUE;
-        This->time_earliest = time;
-    } else
-        This->timevalid = FALSE;
-    LeaveCriticalSection(&This->time_cs);
-    return hr;
-}
-
 static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl =
 {
     MediaSeekingPassThru_QueryInterface,
@@ -870,3 +742,150 @@ static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl =
     MediaPositionPassThru_CanSeekForward,
     MediaPositionPassThru_CanSeekBackward
 };
+
+void strmbase_passthrough_init(PassThruImpl *passthrough, IUnknown *outer)
+{
+    memset(passthrough, 0, sizeof(*passthrough));
+
+    passthrough->outer_unk = outer;
+    passthrough->IMediaPosition_iface.lpVtbl = &IMediaPositionPassThru_Vtbl;
+    passthrough->IMediaSeeking_iface.lpVtbl = &IMediaSeekingPassThru_Vtbl;
+    passthrough->ISeekingPassThru_iface.lpVtbl = &ISeekingPassThru_Vtbl;
+    InitializeCriticalSection(&passthrough->time_cs);
+    passthrough->time_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PassThruImpl.time_cs" );
+}
+
+void strmbase_passthrough_cleanup(PassThruImpl *passthrough)
+{
+    passthrough->time_cs.DebugInfo->Spare[0] = 0;
+    DeleteCriticalSection(&passthrough->time_cs);
+}
+
+struct seeking_passthrough
+{
+    PassThruImpl passthrough;
+
+    IUnknown IUnknown_inner;
+    IUnknown *outer_unk;
+    LONG refcount;
+};
+
+static struct seeking_passthrough *impl_from_IUnknown(IUnknown *iface)
+{
+    return CONTAINING_RECORD(iface, struct seeking_passthrough, IUnknown_inner);
+}
+
+static HRESULT WINAPI seeking_passthrough_QueryInterface(IUnknown *iface, REFIID iid, void **out)
+{
+    struct seeking_passthrough *passthrough = impl_from_IUnknown(iface);
+
+    TRACE("passthrough %p, iid %s, out %p.\n", passthrough, debugstr_guid(iid), out);
+
+    if (IsEqualGUID(iid, &IID_IUnknown))
+        *out = iface;
+    else if (IsEqualGUID(iid, &IID_IMediaPosition))
+        *out = &passthrough->passthrough.IMediaPosition_iface;
+    else if (IsEqualGUID(iid, &IID_IMediaSeeking))
+        *out = &passthrough->passthrough.IMediaSeeking_iface;
+    else if (IsEqualGUID(iid, &IID_ISeekingPassThru))
+        *out = &passthrough->passthrough.ISeekingPassThru_iface;
+    else
+    {
+        *out = NULL;
+        WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown *)*out);
+    return S_OK;
+}
+
+static ULONG WINAPI seeking_passthrough_AddRef(IUnknown *iface)
+{
+    struct seeking_passthrough *passthrough = impl_from_IUnknown(iface);
+    ULONG refcount = InterlockedIncrement(&passthrough->refcount);
+
+    TRACE("%p increasing refcount to %u.\n", passthrough, refcount);
+    return refcount;
+}
+
+static ULONG WINAPI seeking_passthrough_Release(IUnknown *iface)
+{
+    struct seeking_passthrough *passthrough = impl_from_IUnknown(iface);
+    ULONG refcount = InterlockedDecrement(&passthrough->refcount);
+
+    TRACE("%p decreasing refcount to %u.\n", passthrough, refcount);
+    if (!refcount)
+    {
+        strmbase_passthrough_cleanup(&passthrough->passthrough);
+        heap_free(passthrough);
+    }
+    return refcount;
+}
+
+static const IUnknownVtbl seeking_passthrough_vtbl =
+{
+    seeking_passthrough_QueryInterface,
+    seeking_passthrough_AddRef,
+    seeking_passthrough_Release,
+};
+
+HRESULT WINAPI PosPassThru_Construct(IUnknown *outer, void **out)
+{
+    struct seeking_passthrough *object;
+
+    TRACE("outer %p, out %p.\n", outer, out);
+
+    if (!(object = heap_alloc_zero(sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    object->IUnknown_inner.lpVtbl = &seeking_passthrough_vtbl;
+    object->outer_unk = outer ? outer : &object->IUnknown_inner;
+    object->refcount = 1;
+
+    strmbase_passthrough_init(&object->passthrough, object->outer_unk);
+
+    TRACE("Created seeking passthrough %p.\n", object);
+    *out = &object->IUnknown_inner;
+    return S_OK;
+}
+
+HRESULT WINAPI RendererPosPassThru_RegisterMediaTime(IUnknown *iface, REFERENCE_TIME start)
+{
+    struct seeking_passthrough *passthrough = impl_from_IUnknown(iface);
+
+    EnterCriticalSection(&passthrough->passthrough.time_cs);
+    passthrough->passthrough.time_earliest = start;
+    passthrough->passthrough.timevalid = TRUE;
+    LeaveCriticalSection(&passthrough->passthrough.time_cs);
+    return S_OK;
+}
+
+HRESULT WINAPI RendererPosPassThru_ResetMediaTime(IUnknown *iface)
+{
+    struct seeking_passthrough *passthrough = impl_from_IUnknown(iface);
+
+    EnterCriticalSection(&passthrough->passthrough.time_cs);
+    passthrough->passthrough.timevalid = FALSE;
+    LeaveCriticalSection(&passthrough->passthrough.time_cs);
+    return S_OK;
+}
+
+HRESULT WINAPI RendererPosPassThru_EOS(IUnknown *iface)
+{
+    struct seeking_passthrough *passthrough = impl_from_IUnknown(iface);
+    REFERENCE_TIME time;
+    HRESULT hr;
+
+    hr = IMediaSeeking_GetStopPosition(&passthrough->passthrough.IMediaSeeking_iface, &time);
+    EnterCriticalSection(&passthrough->passthrough.time_cs);
+    if (SUCCEEDED(hr))
+    {
+        passthrough->passthrough.timevalid = TRUE;
+        passthrough->passthrough.time_earliest = time;
+    }
+    else
+        passthrough->passthrough.timevalid = FALSE;
+    LeaveCriticalSection(&passthrough->passthrough.time_cs);
+    return hr;
+}
-- 
2.25.1




More information about the wine-devel mailing list