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