Andrew Eikum : mmdevapi: Children of IAudioClient should hold a reference to their parents.
Alexandre Julliard
julliard at winehq.org
Tue Jan 11 10:08:24 CST 2011
Module: wine
Branch: master
Commit: 436d26f935f396de8c6daf2b871b503d6b487484
URL: http://source.winehq.org/git/wine.git/?a=commit;h=436d26f935f396de8c6daf2b871b503d6b487484
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Mon Jan 10 14:10:44 2011 -0600
mmdevapi: Children of IAudioClient should hold a reference to their parents.
---
dlls/mmdevapi/audio.c | 10 ++++
dlls/mmdevapi/tests/render.c | 122 ++++++++++++++++++++++++++++++++++++++----
2 files changed, 121 insertions(+), 11 deletions(-)
diff --git a/dlls/mmdevapi/audio.c b/dlls/mmdevapi/audio.c
index b97dccb..6217cba 100644
--- a/dlls/mmdevapi/audio.c
+++ b/dlls/mmdevapi/audio.c
@@ -1115,12 +1115,14 @@ static HRESULT AudioRenderClient_Create(ACImpl *parent, ACRender **ppv)
This->lpVtbl = &ACRender_Vtbl;
This->ref = 0;
This->parent = parent;
+ AC_AddRef((IAudioClient*)This->parent);
return S_OK;
}
static void AudioRenderClient_Destroy(ACRender *This)
{
This->parent->render = NULL;
+ AC_Release((IAudioClient*)This->parent);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -1313,12 +1315,14 @@ static HRESULT AudioCaptureClient_Create(ACImpl *parent, ACCapture **ppv)
This->lpVtbl = &ACCapture_Vtbl;
This->ref = 0;
This->parent = parent;
+ AC_AddRef((IAudioClient*)This->parent);
return S_OK;
}
static void AudioCaptureClient_Destroy(ACCapture *This)
{
This->parent->capture = NULL;
+ AC_Release((IAudioClient*)This->parent);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -1444,12 +1448,14 @@ static HRESULT AudioSessionControl_Create(ACImpl *parent, ACSession **ppv)
This->lpVtbl = &ACSession_Vtbl;
This->ref = 0;
This->parent = parent;
+ AC_AddRef((IAudioClient*)This->parent);
return S_OK;
}
static void AudioSessionControl_Destroy(ACSession *This)
{
This->parent->session = NULL;
+ AC_Release((IAudioClient*)This->parent);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -1650,12 +1656,14 @@ static HRESULT AudioSimpleVolume_Create(ACImpl *parent, ASVolume **ppv)
This->lpVtbl = &ASVolume_Vtbl;
This->ref = 0;
This->parent = parent;
+ AC_AddRef((IAudioClient*)This->parent);
return S_OK;
}
static void AudioSimpleVolume_Destroy(ASVolume *This)
{
This->parent->svolume = NULL;
+ AC_Release((IAudioClient*)This->parent);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -1756,12 +1764,14 @@ static HRESULT AudioClock_Create(ACImpl *parent, AClock **ppv)
This->lp2Vtbl = &AClock2_Vtbl;
This->ref = 0;
This->parent = parent;
+ AC_AddRef((IAudioClient*)This->parent);
return S_OK;
}
static void AudioClock_Destroy(AClock *This)
{
This->parent->clock = NULL;
+ AC_Release((IAudioClient*)This->parent);
HeapFree(GetProcessHeap(), 0, This);
}
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c
index 9661dbd..22e8c9b 100644
--- a/dlls/mmdevapi/tests/render.c
+++ b/dlls/mmdevapi/tests/render.c
@@ -34,6 +34,8 @@
#include "mmdeviceapi.h"
#include "audioclient.h"
+static IMMDevice *dev = NULL;
+
static void test_uninitialized(IAudioClient *ac)
{
HRESULT hr;
@@ -70,15 +72,23 @@ static void test_uninitialized(IAudioClient *ac)
CloseHandle(handle);
}
-static void test_audioclient(IAudioClient *ac)
+static void test_audioclient(void)
{
+ IAudioClient *ac;
IUnknown *unk;
HRESULT hr;
ULONG ref;
WAVEFORMATEX *pwfx, *pwfx2;
REFERENCE_TIME t1, t2;
+ HANDLE handle;
- HANDLE handle = CreateEventW(NULL, FALSE, FALSE, NULL);
+ hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+ NULL, (void**)&ac);
+ ok(hr == S_OK, "Activation failed with %08x\n", hr);
+ if(hr != S_OK)
+ return;
+
+ handle = CreateEventW(NULL, FALSE, FALSE, NULL);
hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, NULL);
ok(hr == E_POINTER, "QueryInterface(NULL) returned %08x\n", hr);
@@ -224,16 +234,110 @@ static void test_audioclient(IAudioClient *ac)
hr = IAudioClient_Start(ac);
ok(hr == S_OK, "Start on a stopped stream returns %08x\n", hr);
+ IAudioClient_Release(ac);
+
CloseHandle(handle);
CoTaskMemFree(pwfx);
}
+static void test_references(void)
+{
+ IAudioClient *ac;
+ IAudioRenderClient *rc;
+ ISimpleAudioVolume *sav;
+ IAudioClock *acl;
+ WAVEFORMATEX *pwfx;
+ HRESULT hr;
+ ULONG ref;
+
+ /* IAudioRenderClient */
+ hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+ NULL, (void**)&ac);
+ ok(hr == S_OK, "Activation failed with %08x\n", hr);
+ if(hr != S_OK)
+ return;
+
+ hr = IAudioClient_GetMixFormat(ac, &pwfx);
+ ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
+ if(hr != S_OK)
+ return;
+
+ hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
+ 0, pwfx, NULL);
+ ok(hr == S_OK, "Initialize failed: %08x\n", hr);
+
+ hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&rc);
+ ok(hr == S_OK, "GetService failed: %08x\n", hr);
+
+ IAudioRenderClient_AddRef(rc);
+ ref = IAudioRenderClient_Release(rc);
+ ok(ref != 0, "RenderClient_Release gave wrong refcount: %u\n", ref);
+
+ ref = IAudioClient_Release(ac);
+ ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
+
+ ref = IAudioRenderClient_Release(rc);
+ ok(ref == 0, "RenderClient_Release gave wrong refcount: %u\n", ref);
+
+ /* ISimpleAudioVolume */
+ hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+ NULL, (void**)&ac);
+ ok(hr == S_OK, "Activation failed with %08x\n", hr);
+ if(hr != S_OK)
+ return;
+
+ hr = IAudioClient_GetMixFormat(ac, &pwfx);
+ ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
+
+ hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
+ 0, pwfx, NULL);
+ ok(hr == S_OK, "Initialize failed: %08x\n", hr);
+
+ hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav);
+ ok(hr == S_OK, "GetService failed: %08x\n", hr);
+
+ ISimpleAudioVolume_AddRef(sav);
+ ref = ISimpleAudioVolume_Release(sav);
+ ok(ref != 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref);
+
+ ref = IAudioClient_Release(ac);
+ ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
+
+ ref = ISimpleAudioVolume_Release(sav);
+ ok(ref == 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref);
+
+ /* IAudioClock */
+ hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+ NULL, (void**)&ac);
+ ok(hr == S_OK, "Activation failed with %08x\n", hr);
+ if(hr != S_OK)
+ return;
+
+ hr = IAudioClient_GetMixFormat(ac, &pwfx);
+ ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
+
+ hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000,
+ 0, pwfx, NULL);
+ ok(hr == S_OK, "Initialize failed: %08x\n", hr);
+
+ hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl);
+ ok(hr == S_OK, "GetService failed: %08x\n", hr);
+
+ IAudioClock_AddRef(acl);
+ ref = IAudioClock_Release(acl);
+ ok(ref != 0, "AudioClock_Release gave wrong refcount: %u\n", ref);
+
+ ref = IAudioClient_Release(ac);
+ ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref);
+
+ ref = IAudioClock_Release(acl);
+ ok(ref == 0, "AudioClock_Release gave wrong refcount: %u\n", ref);
+}
+
START_TEST(render)
{
HRESULT hr;
IMMDeviceEnumerator *mme = NULL;
- IMMDevice *dev = NULL;
- IAudioClient *ac = NULL;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
@@ -254,13 +358,9 @@ START_TEST(render)
goto cleanup;
}
- hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac);
- ok(hr == S_OK, "Activation failed with %08x\n", hr);
- if (ac)
- {
- test_audioclient(ac);
- IAudioClient_Release(ac);
- }
+ test_audioclient();
+ test_references();
+
IMMDevice_Release(dev);
cleanup:
More information about the wine-cvs
mailing list