mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-15 21:20:29 +00:00
winegstreamer: Implement IQualityControl in MPEG audio decoder.
Signed-off-by: Anton Baskanov <baskanov@gmail.com>
This commit is contained in:
parent
16d93a32e3
commit
ea81a48259
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue