quartz: Create DirectSound device and buffer at filter creation and connection respectively.
This commit is contained in:
parent
bbbd42787c
commit
147b0cf5ac
@ -69,7 +69,6 @@ typedef struct DSoundRenderImpl
|
|||||||
DWORD buf_size;
|
DWORD buf_size;
|
||||||
DWORD write_pos;
|
DWORD write_pos;
|
||||||
DWORD write_loops;
|
DWORD write_loops;
|
||||||
BOOL init;
|
|
||||||
|
|
||||||
DWORD last_play_pos;
|
DWORD last_play_pos;
|
||||||
DWORD play_loops;
|
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)
|
static inline HRESULT DSoundRender_GetPos(DSoundRenderImpl *This, DWORD *pPlayPos, DWORD *pWritePos, REFERENCE_TIME *pRefTime)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
@ -334,22 +246,8 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample)
|
|||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
static HRESULT DSoundRender_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
|
||||||
@ -408,6 +306,13 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
|||||||
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
|
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
|
||||||
hr = DSoundRender_InputPin_Construct(&piInput, DSoundRender_Sample, (LPVOID)pDSoundRender, DSoundRender_QueryAccept, &pDSoundRender->csFilter, (IPin **)&pDSoundRender->pInputPin);
|
hr = DSoundRender_InputPin_Construct(&piInput, DSoundRender_Sample, (LPVOID)pDSoundRender, DSoundRender_QueryAccept, &pDSoundRender->csFilter, (IPin **)&pDSoundRender->pInputPin);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = DirectSoundCreate(NULL, &pDSoundRender->dsound, NULL);
|
||||||
|
if (FAILED(hr))
|
||||||
|
ERR("Cannot create Direct Sound object (%x)\n", hr);
|
||||||
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
pDSoundRender->ppPins[0] = (IPin *)pDSoundRender->pInputPin;
|
pDSoundRender->ppPins[0] = (IPin *)pDSoundRender->pInputPin;
|
||||||
@ -415,6 +320,8 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (pDSoundRender->pInputPin)
|
||||||
|
IPin_Release((IPin*)pDSoundRender->pInputPin);
|
||||||
CoTaskMemFree(pDSoundRender->ppPins);
|
CoTaskMemFree(pDSoundRender->ppPins);
|
||||||
pDSoundRender->csFilter.DebugInfo->Spare[0] = 0;
|
pDSoundRender->csFilter.DebugInfo->Spare[0] = 0;
|
||||||
DeleteCriticalSection(&pDSoundRender->csFilter);
|
DeleteCriticalSection(&pDSoundRender->csFilter);
|
||||||
@ -743,6 +650,114 @@ static const IBaseFilterVtbl DSoundRender_Vtbl =
|
|||||||
DSoundRender_QueryVendorInfo
|
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)
|
static HRESULT WINAPI DSoundRender_InputPin_EndOfStream(IPin * iface)
|
||||||
{
|
{
|
||||||
InputPin* This = (InputPin*)iface;
|
InputPin* This = (InputPin*)iface;
|
||||||
@ -762,14 +777,14 @@ static HRESULT WINAPI DSoundRender_InputPin_EndOfStream(IPin * iface)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const IPinVtbl DSoundRender_InputPin_Vtbl =
|
static const IPinVtbl DSoundRender_InputPin_Vtbl =
|
||||||
{
|
{
|
||||||
InputPin_QueryInterface,
|
InputPin_QueryInterface,
|
||||||
IPinImpl_AddRef,
|
IPinImpl_AddRef,
|
||||||
InputPin_Release,
|
InputPin_Release,
|
||||||
InputPin_Connect,
|
InputPin_Connect,
|
||||||
InputPin_ReceiveConnection,
|
DSoundRender_InputPin_ReceiveConnection,
|
||||||
IPinImpl_Disconnect,
|
DSoundRender_InputPin_Disconnect,
|
||||||
IPinImpl_ConnectedTo,
|
IPinImpl_ConnectedTo,
|
||||||
IPinImpl_ConnectionMediaType,
|
IPinImpl_ConnectionMediaType,
|
||||||
IPinImpl_QueryPinInfo,
|
IPinImpl_QueryPinInfo,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user