From: Anton Baskanov baskanov@gmail.com
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/quartz/tests/mpegaudio.c | 4 +- dlls/winegstreamer/quartz_transform.c | 127 ++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 2 deletions(-)
diff --git a/dlls/quartz/tests/mpegaudio.c b/dlls/quartz/tests/mpegaudio.c index 48322d019a8..d3d5c3d76f0 100644 --- a/dlls/quartz/tests/mpegaudio.c +++ b/dlls/quartz/tests/mpegaudio.c @@ -242,7 +242,7 @@ static void test_interfaces(void)
check_interface(pin, &IID_IMemInputPin, TRUE); check_interface(pin, &IID_IPin, TRUE); - todo_wine check_interface(pin, &IID_IQualityControl, TRUE); + check_interface(pin, &IID_IQualityControl, TRUE); check_interface(pin, &IID_IUnknown, TRUE);
check_interface(pin, &IID_IMediaPosition, FALSE); @@ -255,7 +255,7 @@ static void test_interfaces(void) check_interface(pin, &IID_IPin, TRUE); check_interface(pin, &IID_IMediaPosition, TRUE); check_interface(pin, &IID_IMediaSeeking, TRUE); - todo_wine check_interface(pin, &IID_IQualityControl, TRUE); + check_interface(pin, &IID_IQualityControl, TRUE); check_interface(pin, &IID_IUnknown, TRUE);
check_interface(pin, &IID_IAsyncReader, FALSE); diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c index 7fa18aa7673..7986997abef 100644 --- a/dlls/winegstreamer/quartz_transform.c +++ b/dlls/winegstreamer/quartz_transform.c @@ -35,6 +35,10 @@ struct transform struct strmbase_source source; struct strmbase_passthrough passthrough;
+ IQualityControl sink_IQualityControl_iface; + IQualityControl source_IQualityControl_iface; + IQualityControl *qc_sink; + struct wg_transform *transform;
const struct transform_ops *ops; @@ -272,6 +276,8 @@ static HRESULT transform_sink_query_interface(struct strmbase_pin *pin, REFIID i
if (IsEqualGUID(iid, &IID_IMemInputPin)) *out = &filter->sink.IMemInputPin_iface; + else if (IsEqualGUID(iid, &IID_IQualityControl)) + *out = &filter->sink_IQualityControl_iface; else return E_NOINTERFACE;
@@ -419,6 +425,8 @@ static HRESULT transform_source_query_interface(struct strmbase_pin *pin, REFIID *out = &filter->passthrough.IMediaPosition_iface; else if (IsEqualGUID(iid, &IID_IMediaSeeking)) *out = &filter->passthrough.IMediaSeeking_iface; + else if (IsEqualGUID(iid, &IID_IQualityControl)) + *out = &filter->source_IQualityControl_iface; else return E_NOINTERFACE;
@@ -443,6 +451,122 @@ static const struct strmbase_source_ops source_ops = .pfnDecideBufferSize = transform_source_DecideBufferSize, };
+static struct transform *impl_from_sink_IQualityControl(IQualityControl *iface) +{ + return CONTAINING_RECORD(iface, struct transform, sink_IQualityControl_iface); +} + +static HRESULT WINAPI sink_quality_control_QueryInterface(IQualityControl *iface, REFIID iid, void **out) +{ + struct transform *filter = impl_from_sink_IQualityControl(iface); + return IPin_QueryInterface(&filter->source.pin.IPin_iface, iid, out); +} + +static ULONG WINAPI sink_quality_control_AddRef(IQualityControl *iface) +{ + struct transform *filter = impl_from_sink_IQualityControl(iface); + return IPin_AddRef(&filter->source.pin.IPin_iface); +} + +static ULONG WINAPI sink_quality_control_Release(IQualityControl *iface) +{ + struct transform *filter = impl_from_sink_IQualityControl(iface); + return IPin_Release(&filter->source.pin.IPin_iface); +} + +static HRESULT WINAPI sink_quality_control_Notify(IQualityControl *iface, IBaseFilter *sender, Quality q) +{ + struct transform *filter = impl_from_sink_IQualityControl(iface); + + TRACE("filter %p, sender %p, type %#x, proportion %ld, late %s, timestamp %s.\n", + filter, sender, q.Type, q.Proportion, debugstr_time(q.Late), debugstr_time(q.TimeStamp)); + + return S_OK; +} + +static HRESULT WINAPI sink_quality_control_SetSink(IQualityControl *iface, IQualityControl *sink) +{ + struct transform *filter = impl_from_sink_IQualityControl(iface); + + TRACE("filter %p, sink %p.\n", filter, sink); + + filter->qc_sink = sink; + + return S_OK; +} + +static const IQualityControlVtbl sink_quality_control_vtbl = +{ + sink_quality_control_QueryInterface, + sink_quality_control_AddRef, + sink_quality_control_Release, + sink_quality_control_Notify, + sink_quality_control_SetSink, +}; + +static struct transform *impl_from_source_IQualityControl(IQualityControl *iface) +{ + return CONTAINING_RECORD(iface, struct transform, source_IQualityControl_iface); +} + +static HRESULT WINAPI source_quality_control_QueryInterface(IQualityControl *iface, REFIID iid, void **out) +{ + struct transform *filter = impl_from_source_IQualityControl(iface); + return IPin_QueryInterface(&filter->source.pin.IPin_iface, iid, out); +} + +static ULONG WINAPI source_quality_control_AddRef(IQualityControl *iface) +{ + struct transform *filter = impl_from_source_IQualityControl(iface); + return IPin_AddRef(&filter->source.pin.IPin_iface); +} + +static ULONG WINAPI source_quality_control_Release(IQualityControl *iface) +{ + struct transform *filter = impl_from_source_IQualityControl(iface); + return IPin_Release(&filter->source.pin.IPin_iface); +} + +static HRESULT WINAPI source_quality_control_Notify(IQualityControl *iface, IBaseFilter *sender, Quality q) +{ + struct transform *filter = impl_from_source_IQualityControl(iface); + IQualityControl *peer; + HRESULT hr = VFW_E_NOT_FOUND; + + TRACE("filter %p, sender %p, type %#x, proportion %ld, late %s, timestamp %s.\n", + filter, sender, q.Type, q.Proportion, debugstr_time(q.Late), debugstr_time(q.TimeStamp)); + + if (filter->qc_sink) + return IQualityControl_Notify(filter->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 source_quality_control_SetSink(IQualityControl *iface, IQualityControl *sink) +{ + struct transform *filter = impl_from_source_IQualityControl(iface); + + TRACE("filter %p, sink %p.\n", filter, sink); + + return S_OK; +} + +static const IQualityControlVtbl source_quality_control_vtbl = +{ + source_quality_control_QueryInterface, + source_quality_control_AddRef, + source_quality_control_Release, + source_quality_control_Notify, + source_quality_control_SetSink, +}; + static HRESULT transform_create(IUnknown *outer, const CLSID *clsid, const struct transform_ops *ops, struct transform **out) { struct transform *object; @@ -459,6 +583,9 @@ static HRESULT transform_create(IUnknown *outer, const CLSID *clsid, const struc ISeekingPassThru_Init(&object->passthrough.ISeekingPassThru_iface, FALSE, &object->sink.pin.IPin_iface);
+ object->sink_IQualityControl_iface.lpVtbl = &sink_quality_control_vtbl; + object->source_IQualityControl_iface.lpVtbl = &source_quality_control_vtbl; + object->ops = ops;
*out = object;