Zebediah Figura : strmbase/transform: Reimplement IQualityControl for the source pin.

Alexandre Julliard julliard at winehq.org
Mon Nov 4 16:40:24 CST 2019


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

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Sat Nov  2 22:33:14 2019 -0500

strmbase/transform: Reimplement IQualityControl for the source pin.

There is not enough common code between renderers and transforms to be worth
duplicating.

This fixes a regression introduced by db7eb3327. The wrong impl_from_*()
helper was used in IQualityControl::Notify().

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/strmbase/transform.c | 105 +++++++++++++++++++++++++++++++++-------------
 include/wine/strmbase.h   |   5 ++-
 2 files changed, 80 insertions(+), 30 deletions(-)

diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 266232f57a..f4c2c4be72 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -28,7 +28,6 @@ static const WCHAR wcsOutputPinName[] = {'O','u','t',0};
 
 static const IPinVtbl TransformFilter_InputPin_Vtbl;
 static const IPinVtbl TransformFilter_OutputPin_Vtbl;
-static const IQualityControlVtbl TransformFilter_QualityControl_Vtbl;
 
 static inline TransformFilter *impl_from_IBaseFilter( IBaseFilter *iface )
 {
@@ -149,7 +148,6 @@ static void transform_destroy(struct strmbase_filter *iface)
     filter->csReceive.DebugInfo->Spare[0] = 0;
     DeleteCriticalSection(&filter->csReceive);
     FreeMediaType(&filter->pmt);
-    QualityControlImpl_Destroy(filter->qcimpl);
     IUnknown_Release(filter->seekthru_unk);
     strmbase_filter_cleanup(&filter->filter);
     CoTaskMemFree(filter);
@@ -225,7 +223,7 @@ static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, vo
     TransformFilter *filter = impl_from_source_IPin(&iface->IPin_iface);
 
     if (IsEqualGUID(iid, &IID_IQualityControl))
-        *out = &filter->qcimpl->IQualityControl_iface;
+        *out = &filter->source_IQualityControl_iface;
     else if (IsEqualGUID(iid, &IID_IMediaSeeking))
         return IUnknown_QueryInterface(filter->seekthru_unk, iid, out);
     else
@@ -265,6 +263,80 @@ static const IBaseFilterVtbl transform_vtbl =
     BaseFilterImpl_QueryVendorInfo
 };
 
+static TransformFilter *impl_from_source_IQualityControl(IQualityControl *iface)
+{
+    return CONTAINING_RECORD(iface, TransformFilter, source_IQualityControl_iface);
+}
+
+static HRESULT WINAPI transform_source_qc_QueryInterface(IQualityControl *iface,
+        REFIID iid, void **out)
+{
+    TransformFilter *filter = impl_from_source_IQualityControl(iface);
+    return IPin_QueryInterface(&filter->source.pin.IPin_iface, iid, out);
+}
+
+static ULONG WINAPI transform_source_qc_AddRef(IQualityControl *iface)
+{
+    TransformFilter *filter = impl_from_source_IQualityControl(iface);
+    return IPin_AddRef(&filter->source.pin.IPin_iface);
+}
+
+static ULONG WINAPI transform_source_qc_Release(IQualityControl *iface)
+{
+    TransformFilter *filter = impl_from_source_IQualityControl(iface);
+    return IPin_Release(&filter->source.pin.IPin_iface);
+}
+
+HRESULT WINAPI TransformFilterImpl_Notify(TransformFilter *filter, IBaseFilter *sender, Quality q)
+{
+    IQualityControl *peer;
+    HRESULT hr = S_FALSE;
+
+    if (filter->source_qc_sink)
+        return IQualityControl_Notify(filter->source_qc_sink, &filter->filter.IBaseFilter_iface, q);
+
+    if (filter->sink.pin.peer
+            && SUCCEEDED(IPin_QueryInterface(filter->sink.pin.peer, &IID_IQualityControl, (void **)&peer)))
+    {
+        hr = IQualityControl_Notify(peer, &filter->filter.IBaseFilter_iface, q);
+        IQualityControl_Release(peer);
+    }
+    return hr;
+}
+
+static HRESULT WINAPI transform_source_qc_Notify(IQualityControl *iface,
+        IBaseFilter *sender, Quality q)
+{
+    TransformFilter *filter = impl_from_source_IQualityControl(iface);
+
+    TRACE("filter %p, sender %p, type %#x, proportion %u, late %s, timestamp %s.\n",
+            filter, sender, q.Type, q.Proportion, debugstr_time(q.Late), debugstr_time(q.TimeStamp));
+
+    if (filter->pFuncsTable->pfnNotify)
+        return filter->pFuncsTable->pfnNotify(filter, sender, q);
+    return TransformFilterImpl_Notify(filter, sender, q);
+}
+
+static HRESULT WINAPI transform_source_qc_SetSink(IQualityControl *iface, IQualityControl *sink)
+{
+    TransformFilter *filter = impl_from_source_IQualityControl(iface);
+
+    TRACE("filter %p, sink %p.\n", filter, sink);
+
+    filter->source_qc_sink = sink;
+
+    return S_OK;
+}
+
+static const IQualityControlVtbl source_qc_vtbl =
+{
+    transform_source_qc_QueryInterface,
+    transform_source_qc_AddRef,
+    transform_source_qc_Release,
+    transform_source_qc_Notify,
+    transform_source_qc_SetSink,
+};
+
 static HRESULT strmbase_transform_init(IUnknown *outer, const CLSID *clsid,
         const TransformFilterFuncTable *func_table, TransformFilter *filter)
 {
@@ -285,9 +357,7 @@ static HRESULT strmbase_transform_init(IUnknown *outer, const CLSID *clsid,
 
     strmbase_source_init(&filter->source, &TransformFilter_OutputPin_Vtbl, &filter->filter,
             wcsOutputPinName, &source_ops);
-
-    QualityControlImpl_Create(&filter->sink.pin, &filter->qcimpl);
-    filter->qcimpl->IQualityControl_iface.lpVtbl = &TransformFilter_QualityControl_Vtbl;
+    filter->source_IQualityControl_iface.lpVtbl = &source_qc_vtbl;
 
     filter->seekthru_unk = NULL;
     hr = CoCreateInstance(&CLSID_SeekingPassThru, (IUnknown *)&filter->filter.IBaseFilter_iface,
@@ -335,11 +405,6 @@ HRESULT strmbase_transform_create(LONG filter_size, IUnknown *outer, const CLSID
     return E_FAIL;
 }
 
-HRESULT WINAPI TransformFilterImpl_Notify(TransformFilter *filter, IBaseFilter *sender, Quality qm)
-{
-    return QualityControlImpl_Notify(&filter->qcimpl->IQualityControl_iface, sender, qm);
-}
-
 static HRESULT WINAPI TransformFilter_InputPin_EndOfStream(IPin * iface)
 {
     TransformFilter *filter = impl_from_sink_IPin(iface);
@@ -479,21 +544,3 @@ static const IPinVtbl TransformFilter_OutputPin_Vtbl =
     BaseOutputPinImpl_EndFlush,
     BasePinImpl_NewSegment
 };
-
-static HRESULT WINAPI TransformFilter_QualityControlImpl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality qm) {
-    QualityControlImpl *qc = (QualityControlImpl*)iface;
-    TransformFilter *This = impl_from_source_IPin(&qc->pin->IPin_iface);
-
-    if (This->pFuncsTable->pfnNotify)
-        return This->pFuncsTable->pfnNotify(This, sender, qm);
-    else
-        return TransformFilterImpl_Notify(This, sender, qm);
-}
-
-static const IQualityControlVtbl TransformFilter_QualityControl_Vtbl = {
-    QualityControlImpl_QueryInterface,
-    QualityControlImpl_AddRef,
-    QualityControlImpl_Release,
-    TransformFilter_QualityControlImpl_Notify,
-    QualityControlImpl_SetSink
-};
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index a4920054e6..f92a375a56 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -204,14 +204,17 @@ void strmbase_filter_cleanup(struct strmbase_filter *filter);
 typedef struct TransformFilter
 {
     struct strmbase_filter filter;
+
     struct strmbase_source source;
+    IQualityControl source_IQualityControl_iface;
+    IQualityControl *source_qc_sink;
+
     BaseInputPin sink;
 
     AM_MEDIA_TYPE pmt;
     CRITICAL_SECTION csReceive;
 
     const struct TransformFilterFuncTable * pFuncsTable;
-    struct QualityControlImpl *qcimpl;
     /* IMediaSeeking and IMediaPosition are implemented by ISeekingPassThru */
     IUnknown *seekthru_unk;
 } TransformFilter;




More information about the wine-cvs mailing list