mmdevapi: Children of IAudioClient should hold a reference to their parents.
This commit is contained in:
parent
82efaae0a2
commit
436d26f935
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue