mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-07 00:28:18 +00:00
quartz/tests: Add tests for MPEG audio decoder quality control.
Signed-off-by: Anton Baskanov <baskanov@gmail.com>
This commit is contained in:
parent
ea81a48259
commit
fb0f6b4be4
|
@ -789,11 +789,118 @@ static void test_media_types(void)
|
|||
ok(!ref, "Got outstanding refcount %ld.\n", ref);
|
||||
}
|
||||
|
||||
struct testqc
|
||||
{
|
||||
IQualityControl IQualityControl_iface;
|
||||
IUnknown IUnknown_inner;
|
||||
IUnknown *outer_unk;
|
||||
LONG refcount;
|
||||
IBaseFilter *notify_sender;
|
||||
Quality notify_quality;
|
||||
HRESULT notify_hr;
|
||||
};
|
||||
|
||||
static struct testqc *impl_from_IQualityControl(IQualityControl *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct testqc, IQualityControl_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI testqc_QueryInterface(IQualityControl *iface, REFIID iid, void **out)
|
||||
{
|
||||
struct testqc *qc = impl_from_IQualityControl(iface);
|
||||
return IUnknown_QueryInterface(qc->outer_unk, iid, out);
|
||||
}
|
||||
|
||||
static ULONG WINAPI testqc_AddRef(IQualityControl *iface)
|
||||
{
|
||||
struct testqc *qc = impl_from_IQualityControl(iface);
|
||||
return IUnknown_AddRef(qc->outer_unk);
|
||||
}
|
||||
|
||||
static ULONG WINAPI testqc_Release(IQualityControl *iface)
|
||||
{
|
||||
struct testqc *qc = impl_from_IQualityControl(iface);
|
||||
return IUnknown_Release(qc->outer_unk);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI testqc_Notify(IQualityControl *iface, IBaseFilter *sender, Quality q)
|
||||
{
|
||||
struct testqc *qc = impl_from_IQualityControl(iface);
|
||||
|
||||
qc->notify_sender = sender;
|
||||
qc->notify_quality = q;
|
||||
|
||||
return qc->notify_hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI testqc_SetSink(IQualityControl *iface, IQualityControl *sink)
|
||||
{
|
||||
ok(0, "Unexpected call.\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IQualityControlVtbl testqc_vtbl =
|
||||
{
|
||||
testqc_QueryInterface,
|
||||
testqc_AddRef,
|
||||
testqc_Release,
|
||||
testqc_Notify,
|
||||
testqc_SetSink,
|
||||
};
|
||||
|
||||
static struct testqc *impl_from_qc_IUnknown(IUnknown *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct testqc, IUnknown_inner);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI testqc_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out)
|
||||
{
|
||||
struct testqc *qc = impl_from_qc_IUnknown(iface);
|
||||
|
||||
if (IsEqualIID(iid, &IID_IUnknown))
|
||||
*out = iface;
|
||||
else if (IsEqualIID(iid, &IID_IQualityControl))
|
||||
*out = &qc->IQualityControl_iface;
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
|
||||
IUnknown_AddRef((IUnknown *)*out);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI testqc_inner_AddRef(IUnknown *iface)
|
||||
{
|
||||
struct testqc *qc = impl_from_qc_IUnknown(iface);
|
||||
return InterlockedIncrement(&qc->refcount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI testqc_inner_Release(IUnknown *iface)
|
||||
{
|
||||
struct testqc *qc = impl_from_qc_IUnknown(iface);
|
||||
return InterlockedDecrement(&qc->refcount);
|
||||
}
|
||||
|
||||
static const IUnknownVtbl testqc_inner_vtbl =
|
||||
{
|
||||
testqc_inner_QueryInterface,
|
||||
testqc_inner_AddRef,
|
||||
testqc_inner_Release,
|
||||
};
|
||||
|
||||
static void testqc_init(struct testqc *qc, IUnknown *outer)
|
||||
{
|
||||
memset(qc, 0, sizeof(*qc));
|
||||
qc->IQualityControl_iface.lpVtbl = &testqc_vtbl;
|
||||
qc->IUnknown_inner.lpVtbl = &testqc_inner_vtbl;
|
||||
qc->outer_unk = outer ? outer : &qc->IUnknown_inner;
|
||||
}
|
||||
|
||||
struct testfilter
|
||||
{
|
||||
struct strmbase_filter filter;
|
||||
struct strmbase_source source;
|
||||
struct strmbase_sink sink;
|
||||
struct testqc *qc;
|
||||
const AM_MEDIA_TYPE *mt;
|
||||
unsigned int got_sample, got_new_segment, got_eos, got_begin_flush, got_end_flush;
|
||||
REFERENCE_TIME expected_start_time;
|
||||
|
@ -827,6 +934,19 @@ static const struct strmbase_filter_ops testfilter_ops =
|
|||
.filter_destroy = testfilter_destroy,
|
||||
};
|
||||
|
||||
static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
|
||||
{
|
||||
struct testfilter *filter = impl_from_strmbase_filter(iface->filter);
|
||||
|
||||
if (IsEqualGUID(iid, &IID_IQualityControl) && filter->qc)
|
||||
*out = &filter->qc->IQualityControl_iface;
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
|
||||
IUnknown_AddRef((IUnknown *)*out);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface,
|
||||
IMemInputPin *peer, IMemAllocator **allocator)
|
||||
{
|
||||
|
@ -835,6 +955,7 @@ static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface,
|
|||
|
||||
static const struct strmbase_source_ops testsource_ops =
|
||||
{
|
||||
.base.pin_query_interface = testsource_query_interface,
|
||||
.pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
|
||||
.pfnDecideAllocator = testsource_DecideAllocator,
|
||||
};
|
||||
|
@ -1108,6 +1229,107 @@ static void test_source_allocator(IFilterGraph2 *graph, IMediaControl *control,
|
|||
IFilterGraph2_Disconnect(graph, &testsource->source.pin.IPin_iface);
|
||||
}
|
||||
|
||||
static void test_quality_control(IFilterGraph2 *graph, IBaseFilter *filter,
|
||||
IPin *sink, IPin *source, struct testfilter *testsource, struct testfilter *testsink)
|
||||
{
|
||||
struct testqc testsource_qc;
|
||||
IQualityControl *source_qc;
|
||||
IQualityControl *sink_qc;
|
||||
Quality quality = {0};
|
||||
struct testqc qc;
|
||||
HRESULT hr;
|
||||
|
||||
testqc_init(&testsource_qc, testsource->filter.outer_unk);
|
||||
testqc_init(&qc, NULL);
|
||||
|
||||
hr = IPin_QueryInterface(sink, &IID_IQualityControl, (void **)&sink_qc);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = IPin_QueryInterface(source, &IID_IQualityControl, (void **)&source_qc);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
hr = IQualityControl_Notify(sink_qc, &testsink->filter.IBaseFilter_iface, quality);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
|
||||
ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
|
||||
|
||||
hr = IQualityControl_SetSink(sink_qc, &qc.IQualityControl_iface);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
qc.notify_sender = (IBaseFilter *)0xdeadbeef;
|
||||
memset(&qc.notify_quality, 0xaa, sizeof(qc.notify_quality));
|
||||
hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
ok(qc.notify_sender == filter, "Got sender %p.\n", qc.notify_sender);
|
||||
ok(!memcmp(&qc.notify_quality, &quality, sizeof(quality)), "Quality didn't match.\n");
|
||||
hr = IQualityControl_SetSink(sink_qc, NULL);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
hr = IQualityControl_SetSink(source_qc, &qc.IQualityControl_iface);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
qc.notify_sender = (IBaseFilter *)0xdeadbeef;
|
||||
hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
|
||||
ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
|
||||
ok(qc.notify_sender == (IBaseFilter *)0xdeadbeef, "Got sender %p.\n", qc.notify_sender);
|
||||
hr = IQualityControl_SetSink(source_qc, NULL);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
hr = IFilterGraph2_ConnectDirect(graph, &testsource->source.pin.IPin_iface, sink, &mp2_mt);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
|
||||
ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
|
||||
|
||||
testsource->qc = &testsource_qc;
|
||||
|
||||
qc.notify_sender = (IBaseFilter *)0xdeadbeef;
|
||||
hr = IQualityControl_Notify(sink_qc, &testsink->filter.IBaseFilter_iface, quality);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
ok(qc.notify_sender == (IBaseFilter *)0xdeadbeef, "Got sender %p.\n", qc.notify_sender);
|
||||
|
||||
testsource_qc.notify_sender = (IBaseFilter *)0xdeadbeef;
|
||||
memset(&testsource_qc.notify_quality, 0xaa, sizeof(testsource_qc.notify_quality));
|
||||
hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
ok(testsource_qc.notify_sender == filter, "Got sender %p.\n", testsource_qc.notify_sender);
|
||||
ok(!memcmp(&testsource_qc.notify_quality, &quality, sizeof(quality)), "Quality didn't match.\n");
|
||||
|
||||
testsource_qc.notify_hr = E_FAIL;
|
||||
hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
|
||||
ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
|
||||
testsource_qc.notify_hr = S_OK;
|
||||
|
||||
hr = IQualityControl_SetSink(sink_qc, &qc.IQualityControl_iface);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
qc.notify_sender = (IBaseFilter *)0xdeadbeef;
|
||||
memset(&qc.notify_quality, 0xaa, sizeof(qc.notify_quality));
|
||||
hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
ok(qc.notify_sender == filter, "Got sender %p.\n", qc.notify_sender);
|
||||
ok(!memcmp(&qc.notify_quality, &quality, sizeof(quality)), "Quality didn't match.\n");
|
||||
hr = IQualityControl_SetSink(sink_qc, NULL);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
hr = IQualityControl_SetSink(source_qc, &qc.IQualityControl_iface);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
qc.notify_sender = (IBaseFilter *)0xdeadbeef;
|
||||
hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
ok(qc.notify_sender == (IBaseFilter *)0xdeadbeef, "Got sender %p.\n", qc.notify_sender);
|
||||
hr = IQualityControl_SetSink(source_qc, NULL);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
IFilterGraph2_Disconnect(graph, sink);
|
||||
IFilterGraph2_Disconnect(graph, &testsource->source.pin.IPin_iface);
|
||||
|
||||
hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
|
||||
ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
|
||||
|
||||
IQualityControl_Release(source_qc);
|
||||
IQualityControl_Release(sink_qc);
|
||||
|
||||
testsource->qc = NULL;
|
||||
}
|
||||
|
||||
static void test_sample_processing(IMediaControl *control, IMemInputPin *input, struct testfilter *sink)
|
||||
{
|
||||
REFERENCE_TIME start, stop;
|
||||
|
@ -1333,6 +1555,7 @@ static void test_connect_pin(void)
|
|||
IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
|
||||
|
||||
test_source_allocator(graph, control, sink, source, &testsource, &testsink);
|
||||
test_quality_control(graph, filter, sink, source, &testsource, &testsink);
|
||||
|
||||
/* Test sink connection. */
|
||||
|
||||
|
|
Loading…
Reference in a new issue