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