Module: wine Branch: master Commit: 436d26f935f396de8c6daf2b871b503d6b487484 URL: http://source.winehq.org/git/wine.git/?a=commit;h=436d26f935f396de8c6daf2b87...
Author: Andrew Eikum aeikum@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: