Anton Baskanov : winegstreamer: Implement IQualityControl in MPEG audio decoder.
Alexandre Julliard
julliard at winehq.org
Tue May 24 15:55:02 CDT 2022
Module: wine
Branch: master
Commit: ea81a48259804c2ed0aa74d98e1362e5ad7f76ef
URL: https://source.winehq.org/git/wine.git/?a=commit;h=ea81a48259804c2ed0aa74d98e1362e5ad7f76ef
Author: Anton Baskanov <baskanov at gmail.com>
Date: Wed Apr 13 11:37:23 2022 +0700
winegstreamer: Implement IQualityControl in MPEG audio decoder.
Signed-off-by: Anton Baskanov <baskanov at 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;
More information about the wine-cvs
mailing list