Chris Robinson : quartz:
Create DirectSound device and buffer at filter creation and connection
respectively .
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Apr 16 07:08:40 CDT 2007
Module: wine
Branch: master
Commit: 147b0cf5acbde59d3b6a15bfe53da1fc938c6854
URL: http://source.winehq.org/git/wine.git/?a=commit;h=147b0cf5acbde59d3b6a15bfe53da1fc938c6854
Author: Chris Robinson <chris.kcat at gmail.com>
Date: Fri Apr 13 09:32:56 2007 -0700
quartz: Create DirectSound device and buffer at filter creation and connection respectively.
---
dlls/quartz/dsoundrender.c | 227 +++++++++++++++++++++++--------------------
1 files changed, 121 insertions(+), 106 deletions(-)
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c
index ed2eda2..2492052 100644
--- a/dlls/quartz/dsoundrender.c
+++ b/dlls/quartz/dsoundrender.c
@@ -69,7 +69,6 @@ typedef struct DSoundRenderImpl
DWORD buf_size;
DWORD write_pos;
DWORD write_loops;
- BOOL init;
DWORD last_play_pos;
DWORD play_loops;
@@ -108,93 +107,6 @@ static HRESULT DSoundRender_InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLE
}
-static HRESULT DSoundRender_CreateSoundBuffer(IBaseFilter * iface)
-{
- HRESULT hr;
- WAVEFORMATEX wav_fmt;
- AM_MEDIA_TYPE amt;
- WAVEFORMATEX* format;
- DSBUFFERDESC buf_desc;
- DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
-
- hr = IPin_ConnectionMediaType(This->ppPins[0], &amt);
- if (FAILED(hr)) {
- ERR("Unable to retrieve media type\n");
- return hr;
- }
-
- TRACE("MajorType %s\n", debugstr_guid(&amt.majortype));
- TRACE("SubType %s\n", debugstr_guid(&amt.subtype));
- TRACE("Format %s\n", debugstr_guid(&amt.formattype));
- TRACE("Size %d\n", amt.cbFormat);
-
- dump_AM_MEDIA_TYPE(&amt);
-
- format = (WAVEFORMATEX*)amt.pbFormat;
- TRACE("wFormatTag = %x %x\n", format->wFormatTag, WAVE_FORMAT_PCM);
- TRACE("nChannels = %d\n", format->nChannels);
- TRACE("nSamplesPerSec = %u\n", format->nSamplesPerSec);
- TRACE("nAvgBytesPerSec = %u\n", format->nAvgBytesPerSec);
- TRACE("nBlockAlign = %d\n", format->nBlockAlign);
- TRACE("wBitsPerSample = %d\n", format->wBitsPerSample);
- TRACE("cbSize = %d\n", format->cbSize);
-
- /* Lock the critical section to make sure we're still marked to play while
- setting up the playback buffer */
- EnterCriticalSection(&This->csFilter);
-
- if (This->state != State_Running) {
- hr = VFW_E_WRONG_STATE;
- goto getout;
- }
-
- hr = DirectSoundCreate(NULL, &This->dsound, NULL);
- if (FAILED(hr)) {
- ERR("Cannot create Direct Sound object\n");
- goto getout;
- }
-
- This->buf_size = format->nAvgBytesPerSec;
-
- wav_fmt = *format;
- wav_fmt.cbSize = 0;
-
- memset(&buf_desc,0,sizeof(DSBUFFERDESC));
- buf_desc.dwSize = sizeof(DSBUFFERDESC);
- buf_desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN |
- DSBCAPS_CTRLFREQUENCY | DSBCAPS_GETCURRENTPOSITION2;
- buf_desc.dwBufferBytes = This->buf_size;
- buf_desc.lpwfxFormat = &wav_fmt;
- hr = IDirectSound_CreateSoundBuffer(This->dsound, &buf_desc, &This->dsbuffer, NULL);
- if (FAILED(hr)) {
- ERR("Can't create sound buffer !\n");
- IDirectSound_Release(This->dsound);
- goto getout;
- }
-
- hr = IDirectSoundBuffer_SetVolume(This->dsbuffer, This->volume);
- if (FAILED(hr))
- ERR("Can't set volume to %ld (%x)!\n", This->volume, hr);
-
- hr = IDirectSoundBuffer_SetPan(This->dsbuffer, This->pan);
- if (FAILED(hr))
- ERR("Can't set pan to %ld (%x)!\n", This->pan, hr);
-
- hr = IDirectSoundBuffer_Play(This->dsbuffer, 0, 0, DSBPLAY_LOOPING);
- if (FAILED(hr)) {
- ERR("Can't start sound buffer (%x)!\n", hr);
- IDirectSoundBuffer_Release(This->dsbuffer);
- IDirectSound_Release(This->dsound);
- goto getout;
- }
-
- This->write_pos = 0;
-
-getout:
- LeaveCriticalSection(&This->csFilter);
- return hr;
-}
-
static inline HRESULT DSoundRender_GetPos(DSoundRenderImpl *This, DWORD *pPlayPos, DWORD *pWritePos, REFERENCE_TIME *pRefTime)
{
HRESULT hr;
@@ -334,22 +246,8 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample)
TRACE("\n");
}
#endif
-
- if (!This->init)
- {
- hr = DSoundRender_CreateSoundBuffer(iface);
- if (SUCCEEDED(hr))
- This->init = TRUE;
- else
- {
- ERR("Unable to create DSound buffer\n");
- return hr;
- }
- }
-
- hr = DSoundRender_SendSampleData(This, pbSrcStream, cbSrcStream);
- return hr;
+ return DSoundRender_SendSampleData(This, pbSrcStream, cbSrcStream);
}
static HRESULT DSoundRender_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
@@ -410,11 +308,20 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
if (SUCCEEDED(hr))
{
+ hr = DirectSoundCreate(NULL, &pDSoundRender->dsound, NULL);
+ if (FAILED(hr))
+ ERR("Cannot create Direct Sound object (%x)\n", hr);
+ }
+
+ if (SUCCEEDED(hr))
+ {
pDSoundRender->ppPins[0] = (IPin *)pDSoundRender->pInputPin;
*ppv = (LPVOID)pDSoundRender;
}
else
{
+ if (pDSoundRender->pInputPin)
+ IPin_Release((IPin*)pDSoundRender->pInputPin);
CoTaskMemFree(pDSoundRender->ppPins);
pDSoundRender->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&pDSoundRender->csFilter);
@@ -743,6 +650,114 @@ static const IBaseFilterVtbl DSoundRender_Vtbl =
DSoundRender_QueryVendorInfo
};
+static HRESULT WINAPI DSoundRender_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
+{
+ InputPin *This = (InputPin *)iface;
+ PIN_DIRECTION pindirReceive;
+ DSoundRenderImpl *DSImpl;
+ HRESULT hr = S_OK;
+
+ TRACE("(%p)->(%p, %p)\n", This, pReceivePin, pmt);
+ dump_AM_MEDIA_TYPE(pmt);
+
+ EnterCriticalSection(This->pin.pCritSec);
+ {
+ DSImpl = (DSoundRenderImpl*)This->pin.pinInfo.pFilter;
+
+ if (This->pin.pConnectedTo)
+ hr = VFW_E_ALREADY_CONNECTED;
+
+ if (SUCCEEDED(hr) && This->pin.fnQueryAccept(This->pin.pUserData, pmt) != S_OK)
+ hr = VFW_E_TYPE_NOT_ACCEPTED;
+
+ if (SUCCEEDED(hr))
+ {
+ IPin_QueryDirection(pReceivePin, &pindirReceive);
+
+ if (pindirReceive != PINDIR_OUTPUT)
+ {
+ ERR("Can't connect from non-output pin\n");
+ hr = VFW_E_INVALID_DIRECTION;
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ WAVEFORMATEX *format;
+ DSBUFFERDESC buf_desc;
+
+ TRACE("MajorType %s\n", debugstr_guid(&pmt->majortype));
+ TRACE("SubType %s\n", debugstr_guid(&pmt->subtype));
+ TRACE("Format %s\n", debugstr_guid(&pmt->formattype));
+ TRACE("Size %d\n", pmt->cbFormat);
+
+ format = (WAVEFORMATEX*)pmt->pbFormat;
+
+ DSImpl->buf_size = format->nAvgBytesPerSec;
+
+ memset(&buf_desc,0,sizeof(DSBUFFERDESC));
+ buf_desc.dwSize = sizeof(DSBUFFERDESC);
+ buf_desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN |
+ DSBCAPS_CTRLFREQUENCY |
+ DSBCAPS_GETCURRENTPOSITION2;
+ buf_desc.dwBufferBytes = DSImpl->buf_size;
+ buf_desc.lpwfxFormat = format;
+ hr = IDirectSound_CreateSoundBuffer(DSImpl->dsound, &buf_desc, &DSImpl->dsbuffer, NULL);
+ if (FAILED(hr))
+ ERR("Can't create sound buffer (%x)\n", hr);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = IDirectSoundBuffer_SetVolume(DSImpl->dsbuffer, DSImpl->volume);
+ if (FAILED(hr))
+ ERR("Can't set volume to %ld (%x)\n", DSImpl->volume, hr);
+
+ hr = IDirectSoundBuffer_SetPan(DSImpl->dsbuffer, DSImpl->pan);
+ if (FAILED(hr))
+ ERR("Can't set pan to %ld (%x)\n", DSImpl->pan, hr);
+
+ DSImpl->write_pos = 0;
+ hr = S_OK;
+ if (DSImpl->state == State_Running)
+ hr = IDirectSoundBuffer_Play(DSImpl->dsbuffer, 0, 0, DSBPLAY_LOOPING);
+ if (FAILED(hr))
+ ERR("Can't play sound buffer (%x)\n", hr);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ CopyMediaType(&This->pin.mtCurrent, pmt);
+ This->pin.pConnectedTo = pReceivePin;
+ IPin_AddRef(pReceivePin);
+ }
+ else
+ {
+ if (DSImpl->dsbuffer)
+ IDirectSoundBuffer_Release(DSImpl->dsbuffer);
+ DSImpl->dsbuffer = NULL;
+ }
+ }
+ LeaveCriticalSection(This->pin.pCritSec);
+
+ return hr;
+}
+
+static HRESULT WINAPI DSoundRender_InputPin_Disconnect(IPin * iface)
+{
+ IPinImpl *This = (IPinImpl*)iface;
+ DSoundRenderImpl *DSImpl;
+
+ TRACE("(%p)->()\n", iface);
+
+ DSImpl = (DSoundRenderImpl*)This->pinInfo.pFilter;
+ if (DSImpl->dsbuffer)
+ IDirectSoundBuffer_Release(DSImpl->dsbuffer);
+ DSImpl->dsbuffer = NULL;
+
+ return IPinImpl_Disconnect(iface);
+}
+
static HRESULT WINAPI DSoundRender_InputPin_EndOfStream(IPin * iface)
{
InputPin* This = (InputPin*)iface;
@@ -762,14 +777,14 @@ static HRESULT WINAPI DSoundRender_InputPin_EndOfStream(IPin * iface)
return hr;
}
-static const IPinVtbl DSoundRender_InputPin_Vtbl =
+static const IPinVtbl DSoundRender_InputPin_Vtbl =
{
InputPin_QueryInterface,
IPinImpl_AddRef,
InputPin_Release,
InputPin_Connect,
- InputPin_ReceiveConnection,
- IPinImpl_Disconnect,
+ DSoundRender_InputPin_ReceiveConnection,
+ DSoundRender_InputPin_Disconnect,
IPinImpl_ConnectedTo,
IPinImpl_ConnectionMediaType,
IPinImpl_QueryPinInfo,
More information about the wine-cvs
mailing list