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@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2019-11-02 22:33:14 -05:00 committed by Alexandre Julliard
parent acb2e4fc7a
commit cdeb55a8f9
2 changed files with 80 additions and 30 deletions

View file

@ -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
};

View file

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