Commit ea81a482 authored by Anton Baskanov's avatar Anton Baskanov Committed by Alexandre Julliard

winegstreamer: Implement IQualityControl in MPEG audio decoder.

parent 16d93a32
......@@ -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);
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment