mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-14 17:46:23 +00:00
mf/tests: Allocate test callbacks dynamically and check refcounts.
This commit is contained in:
parent
c9b6972231
commit
96163508b1
|
@ -1792,8 +1792,14 @@ static const struct test_stream_sink test_stream_sink = {.IMFStreamSink_iface.lp
|
|||
struct test_callback
|
||||
{
|
||||
IMFAsyncCallback IMFAsyncCallback_iface;
|
||||
LONG refcount;
|
||||
};
|
||||
|
||||
static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
|
||||
|
@ -1810,12 +1816,21 @@ static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFII
|
|||
|
||||
static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
|
||||
{
|
||||
return 2;
|
||||
struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
|
||||
return InterlockedIncrement(&callback->refcount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
|
||||
{
|
||||
return 1;
|
||||
struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
|
||||
ULONG refcount = InterlockedDecrement(&callback->refcount);
|
||||
|
||||
if (!refcount)
|
||||
{
|
||||
free(callback);
|
||||
}
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
|
||||
|
@ -1840,20 +1855,35 @@ static const IMFAsyncCallbackVtbl testcallbackvtbl =
|
|||
testcallback_Invoke,
|
||||
};
|
||||
|
||||
static void init_test_callback(struct test_callback *callback)
|
||||
static IMFAsyncCallback *create_test_callback(void)
|
||||
{
|
||||
struct test_callback *callback;
|
||||
|
||||
if (!(callback = calloc(1, sizeof(*callback))))
|
||||
return NULL;
|
||||
|
||||
callback->refcount = 1;
|
||||
callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl;
|
||||
|
||||
return &callback->IMFAsyncCallback_iface;
|
||||
}
|
||||
|
||||
static void test_session_events(IMFMediaSession *session)
|
||||
static void test_media_session_events(void)
|
||||
{
|
||||
struct test_callback callback, callback2;
|
||||
IMFAsyncCallback *callback, *callback2;
|
||||
IMFMediaSession *session;
|
||||
IMFAsyncResult *result;
|
||||
IMFMediaEvent *event;
|
||||
HRESULT hr;
|
||||
|
||||
init_test_callback(&callback);
|
||||
init_test_callback(&callback2);
|
||||
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
|
||||
ok(hr == S_OK, "Startup failure, hr %#lx.\n", hr);
|
||||
|
||||
callback = create_test_callback();
|
||||
callback2 = create_test_callback();
|
||||
|
||||
hr = MFCreateMediaSession(NULL, &session);
|
||||
ok(hr == S_OK, "Failed to create media session, hr %#lx.\n", hr);
|
||||
|
||||
hr = IMFMediaSession_GetEvent(session, MF_EVENT_FLAG_NO_WAIT, &event);
|
||||
ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
|
||||
|
@ -1862,26 +1892,31 @@ static void test_session_events(IMFMediaSession *session)
|
|||
hr = IMFMediaSession_BeginGetEvent(session, NULL, NULL);
|
||||
ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session);
|
||||
hr = IMFMediaSession_BeginGetEvent(session, callback, (IUnknown *)session);
|
||||
ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
|
||||
EXPECT_REF(callback, 2);
|
||||
|
||||
/* Same callback, same state. */
|
||||
hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session);
|
||||
hr = IMFMediaSession_BeginGetEvent(session, callback, (IUnknown *)session);
|
||||
ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
|
||||
EXPECT_REF(callback, 2);
|
||||
|
||||
/* Same callback, different state. */
|
||||
hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface);
|
||||
hr = IMFMediaSession_BeginGetEvent(session, callback, (IUnknown *)callback);
|
||||
ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
|
||||
EXPECT_REF(callback, 2);
|
||||
|
||||
/* Different callback, same state. */
|
||||
hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)session);
|
||||
hr = IMFMediaSession_BeginGetEvent(session, callback2, (IUnknown *)session);
|
||||
ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
|
||||
EXPECT_REF(callback2, 1);
|
||||
|
||||
/* Different callback, different state. */
|
||||
hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface);
|
||||
hr = IMFMediaSession_BeginGetEvent(session, callback2, (IUnknown *)callback);
|
||||
ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
|
||||
EXPECT_REF(callback, 2);
|
||||
|
||||
hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
|
||||
hr = MFCreateAsyncResult(NULL, callback, NULL, &result);
|
||||
ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
|
||||
|
||||
hr = IMFMediaSession_EndGetEvent(session, result, &event);
|
||||
|
@ -1890,6 +1925,17 @@ static void test_session_events(IMFMediaSession *session)
|
|||
/* Shutdown behavior. */
|
||||
hr = IMFMediaSession_Shutdown(session);
|
||||
ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
|
||||
IMFMediaSession_Release(session);
|
||||
|
||||
/* Shutdown leaks callback */
|
||||
EXPECT_REF(callback, 2);
|
||||
EXPECT_REF(callback2, 1);
|
||||
|
||||
IMFAsyncCallback_Release(callback);
|
||||
IMFAsyncCallback_Release(callback2);
|
||||
|
||||
hr = MFShutdown();
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
}
|
||||
|
||||
static void test_media_session(void)
|
||||
|
@ -1903,8 +1949,8 @@ static void test_media_session(void)
|
|||
PROPVARIANT propvar;
|
||||
IMFGetService *gs;
|
||||
IMFClock *clock;
|
||||
DWORD caps;
|
||||
HRESULT hr;
|
||||
DWORD caps;
|
||||
|
||||
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
|
||||
ok(hr == S_OK, "Startup failure, hr %#lx.\n", hr);
|
||||
|
@ -2007,17 +2053,6 @@ static void test_media_session(void)
|
|||
IMFMediaSession_Release(session);
|
||||
|
||||
IMFAttributes_Release(attributes);
|
||||
|
||||
/* Basic events behavior. */
|
||||
hr = MFCreateMediaSession(NULL, &session);
|
||||
ok(hr == S_OK, "Failed to create media session, hr %#lx.\n", hr);
|
||||
|
||||
test_session_events(session);
|
||||
|
||||
IMFMediaSession_Release(session);
|
||||
|
||||
hr = MFShutdown();
|
||||
ok(hr == S_OK, "Shutdown failure, hr %#lx.\n", hr);
|
||||
}
|
||||
|
||||
static void test_media_session_rate_control(void)
|
||||
|
@ -9795,6 +9830,7 @@ START_TEST(mf)
|
|||
test_MFGetService();
|
||||
test_sequencer_source();
|
||||
test_media_session();
|
||||
test_media_session_events();
|
||||
test_media_session_rate_control();
|
||||
test_MFShutdownObject();
|
||||
test_presentation_clock();
|
||||
|
|
Loading…
Reference in a new issue