mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
Implemented CLSID_AudioRender.
This commit is contained in:
parent
aacac86ada
commit
6619ebad32
@ -10,6 +10,7 @@ SYMBOLFILE = $(MODULE).tmp.o
|
||||
|
||||
C_SRCS = \
|
||||
amundoc.c \
|
||||
audren.c \
|
||||
basefilt.c \
|
||||
basepin.c \
|
||||
complist.c \
|
||||
|
841
dlls/quartz/audren.c
Normal file
841
dlls/quartz/audren.c
Normal file
@ -0,0 +1,841 @@
|
||||
/*
|
||||
* Audio Renderer (CLSID_AudioRender)
|
||||
*
|
||||
* FIXME
|
||||
* - implements IRefereneceClock.
|
||||
* - implements seeking.
|
||||
*
|
||||
* hidenori@a2.ctktv.ne.jp
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "mmsystem.h"
|
||||
#include "winerror.h"
|
||||
#include "wine/obj_base.h"
|
||||
#include "wine/obj_oleaut.h"
|
||||
#include "strmif.h"
|
||||
#include "control.h"
|
||||
#include "vfwmsgs.h"
|
||||
#include "uuids.h"
|
||||
|
||||
#include "debugtools.h"
|
||||
DEFAULT_DEBUG_CHANNEL(quartz);
|
||||
|
||||
#include "quartz_private.h"
|
||||
#include "audren.h"
|
||||
|
||||
|
||||
static const WCHAR QUARTZ_AudioRender_Name[] =
|
||||
{ 'A','u','d','i','o',' ','R','e','n','d','e','r',0 };
|
||||
static const WCHAR QUARTZ_AudioRenderPin_Name[] =
|
||||
{ 'I','n',0 };
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* CAudioRendererImpl waveOut methods (internal)
|
||||
*
|
||||
*/
|
||||
|
||||
static
|
||||
HRESULT QUARTZ_HRESULT_From_MMRESULT( MMRESULT mr )
|
||||
{
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
switch ( mr )
|
||||
{
|
||||
case MMSYSERR_NOERROR:
|
||||
hr = S_OK;
|
||||
break;
|
||||
case MMSYSERR_NOMEM:
|
||||
hr = E_OUTOFMEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void CAudioRendererImpl_waveOutEventCallback(
|
||||
HWAVEOUT hwo, UINT uMsg,
|
||||
DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
|
||||
{
|
||||
CAudioRendererImpl* This = (CAudioRendererImpl*)dwInstance;
|
||||
|
||||
if ( uMsg == WOM_DONE )
|
||||
SetEvent( This->m_hEventRender );
|
||||
}
|
||||
|
||||
static
|
||||
void CAudioRendererImpl_waveOutReset(
|
||||
CAudioRendererImpl* This )
|
||||
{
|
||||
if ( !This->m_fWaveOutInit )
|
||||
return;
|
||||
|
||||
waveOutReset( This->m_hWaveOut );
|
||||
SetEvent( This->m_hEventRender );
|
||||
}
|
||||
|
||||
static
|
||||
void CAudioRendererImpl_waveOutUninit(
|
||||
CAudioRendererImpl* This )
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if ( !This->m_fWaveOutInit )
|
||||
return;
|
||||
|
||||
waveOutReset( This->m_hWaveOut );
|
||||
SetEvent( This->m_hEventRender );
|
||||
|
||||
for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
|
||||
{
|
||||
if ( This->m_hdr[i].dwFlags & WHDR_PREPARED )
|
||||
{
|
||||
waveOutUnprepareHeader(
|
||||
This->m_hWaveOut,
|
||||
&This->m_hdr[i], sizeof(WAVEHDR) );
|
||||
This->m_hdr[i].dwFlags = 0;
|
||||
}
|
||||
if ( This->m_hdr[i].lpData != NULL )
|
||||
{
|
||||
QUARTZ_FreeMem( This->m_hdr[i].lpData );
|
||||
This->m_hdr[i].lpData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
waveOutClose( This->m_hWaveOut );
|
||||
This->m_hWaveOut = (HWAVEOUT)NULL;
|
||||
if ( This->m_hEventRender != (HANDLE)NULL )
|
||||
{
|
||||
CloseHandle( This->m_hEventRender );
|
||||
This->m_hEventRender = (HANDLE)NULL;
|
||||
}
|
||||
|
||||
This->m_fWaveOutInit = FALSE;
|
||||
}
|
||||
|
||||
static
|
||||
HRESULT CAudioRendererImpl_waveOutInit(
|
||||
CAudioRendererImpl* This, WAVEFORMATEX* pwfx )
|
||||
{
|
||||
MMRESULT mr;
|
||||
HRESULT hr;
|
||||
DWORD i;
|
||||
DWORD dwBlockSize;
|
||||
|
||||
if ( This->m_fWaveOutInit )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if ( pwfx == NULL )
|
||||
return E_POINTER;
|
||||
if ( pwfx->nBlockAlign == 0 )
|
||||
return E_INVALIDARG;
|
||||
|
||||
This->m_hEventRender = (HANDLE)NULL;
|
||||
This->m_hWaveOut = (HWAVEOUT)NULL;
|
||||
This->m_dwBlockSize = 0;
|
||||
This->m_phdrCur = NULL;
|
||||
ZeroMemory( &This->m_hdr, sizeof(This->m_hdr) );
|
||||
|
||||
|
||||
mr = waveOutOpen(
|
||||
&This->m_hWaveOut, WAVE_MAPPER, pwfx,
|
||||
(DWORD)CAudioRendererImpl_waveOutEventCallback, (DWORD)This,
|
||||
CALLBACK_FUNCTION );
|
||||
hr = QUARTZ_HRESULT_From_MMRESULT( mr );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
This->m_fWaveOutInit = TRUE;
|
||||
|
||||
This->m_hEventRender = CreateEventA(
|
||||
NULL, TRUE, TRUE, NULL );
|
||||
if ( This->m_hEventRender == (HANDLE)NULL )
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
dwBlockSize = pwfx->nAvgBytesPerSec / pwfx->nBlockAlign;
|
||||
if ( dwBlockSize == 0 )
|
||||
dwBlockSize = 1;
|
||||
dwBlockSize *= pwfx->nBlockAlign;
|
||||
This->m_dwBlockSize = dwBlockSize;
|
||||
|
||||
for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
|
||||
{
|
||||
This->m_hdr[i].lpData = (CHAR*)QUARTZ_AllocMem( dwBlockSize );
|
||||
if ( This->m_hdr[i].lpData == NULL )
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto err;
|
||||
}
|
||||
mr = waveOutPrepareHeader(
|
||||
This->m_hWaveOut,
|
||||
&This->m_hdr[i], sizeof(WAVEHDR) );
|
||||
hr = QUARTZ_HRESULT_From_MMRESULT( mr );
|
||||
if ( FAILED(hr) )
|
||||
goto err;
|
||||
This->m_hdr[i].dwFlags |= WHDR_DONE;
|
||||
This->m_hdr[i].dwBufferLength = dwBlockSize;
|
||||
This->m_hdr[i].dwUser = i;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
err:
|
||||
CAudioRendererImpl_waveOutUninit(This);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static
|
||||
WAVEHDR* CAudioRendererImpl_waveOutGetBuffer(
|
||||
CAudioRendererImpl* This )
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
if ( !This->m_fWaveOutInit )
|
||||
return NULL;
|
||||
|
||||
if ( This->m_phdrCur != NULL )
|
||||
return This->m_phdrCur;
|
||||
|
||||
for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
|
||||
{
|
||||
if ( This->m_hdr[i].dwFlags & WHDR_DONE )
|
||||
{
|
||||
This->m_phdrCur = &(This->m_hdr[i]);
|
||||
This->m_phdrCur->dwFlags &= ~WHDR_DONE;
|
||||
This->m_phdrCur->dwBufferLength = 0;
|
||||
return This->m_phdrCur;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
HRESULT CAudioRendererImpl_waveOutWriteData(
|
||||
CAudioRendererImpl* This,
|
||||
const BYTE* pData, DWORD cbData, DWORD* pcbWritten )
|
||||
{
|
||||
DWORD cbAvail;
|
||||
|
||||
*pcbWritten = 0;
|
||||
|
||||
if ( !This->m_fWaveOutInit )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if ( cbData == 0 )
|
||||
return S_OK;
|
||||
|
||||
if ( CAudioRendererImpl_waveOutGetBuffer(This) == NULL )
|
||||
return S_FALSE;
|
||||
|
||||
cbAvail = This->m_dwBlockSize - This->m_phdrCur->dwBufferLength;
|
||||
if ( cbAvail > cbData )
|
||||
cbAvail = cbData;
|
||||
memcpy( This->m_phdrCur->lpData, pData, cbAvail );
|
||||
pData += cbAvail;
|
||||
cbData -= cbAvail;
|
||||
This->m_phdrCur->dwBufferLength += cbAvail;
|
||||
|
||||
*pcbWritten = cbAvail;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static
|
||||
HRESULT CAudioRendererImpl_waveOutFlush(
|
||||
CAudioRendererImpl* This )
|
||||
{
|
||||
MMRESULT mr;
|
||||
HRESULT hr;
|
||||
|
||||
if ( !This->m_fWaveOutInit )
|
||||
return E_UNEXPECTED;
|
||||
if ( This->m_phdrCur == NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if ( This->m_phdrCur->dwBufferLength == 0 )
|
||||
return S_OK;
|
||||
|
||||
mr = waveOutWrite(
|
||||
This->m_hWaveOut,
|
||||
This->m_phdrCur, sizeof(WAVEHDR) );
|
||||
hr = QUARTZ_HRESULT_From_MMRESULT( mr );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
This->m_phdrCur = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static
|
||||
HRESULT CAudioRendererImpl_waveOutGetVolume(
|
||||
CAudioRendererImpl* This,
|
||||
DWORD* pdwLeft, DWORD* pdwRight )
|
||||
{
|
||||
MMRESULT mr;
|
||||
HRESULT hr;
|
||||
DWORD dwVol;
|
||||
|
||||
if ( !This->m_fWaveOutInit )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
mr = waveOutGetVolume(
|
||||
This->m_hWaveOut, &dwVol );
|
||||
hr = QUARTZ_HRESULT_From_MMRESULT( mr );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
*pdwLeft = LOWORD(dwVol);
|
||||
*pdwRight = HIWORD(dwVol);
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static
|
||||
HRESULT CAudioRendererImpl_waveOutSetVolume(
|
||||
CAudioRendererImpl* This,
|
||||
DWORD dwLeft, DWORD dwRight )
|
||||
{
|
||||
MMRESULT mr;
|
||||
DWORD dwVol;
|
||||
|
||||
if ( !This->m_fWaveOutInit )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
dwVol = dwLeft | (dwRight<<16);
|
||||
|
||||
mr = waveOutSetVolume(
|
||||
This->m_hWaveOut, dwVol );
|
||||
return QUARTZ_HRESULT_From_MMRESULT( mr );
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* CAudioRendererImpl methods
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
static HRESULT CAudioRendererImpl_OnActive( CBaseFilterImpl* pImpl )
|
||||
{
|
||||
CAudioRendererImpl_THIS(pImpl,basefilter);
|
||||
WAVEFORMATEX* pwfx;
|
||||
|
||||
FIXME( "(%p)\n", This );
|
||||
|
||||
if ( This->pPin->pin.pmtConn == NULL )
|
||||
return NOERROR;
|
||||
|
||||
pwfx = (WAVEFORMATEX*)This->pPin->pin.pmtConn->pbFormat;
|
||||
if ( pwfx == NULL )
|
||||
return E_FAIL;
|
||||
|
||||
This->m_fInFlush = FALSE;
|
||||
|
||||
return CAudioRendererImpl_waveOutInit(This,pwfx);
|
||||
}
|
||||
|
||||
static HRESULT CAudioRendererImpl_OnInactive( CBaseFilterImpl* pImpl )
|
||||
{
|
||||
CAudioRendererImpl_THIS(pImpl,basefilter);
|
||||
|
||||
FIXME( "(%p)\n", This );
|
||||
|
||||
CAudioRendererImpl_waveOutUninit(This);
|
||||
|
||||
This->m_fInFlush = FALSE;
|
||||
|
||||
TRACE("returned\n" );
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static const CBaseFilterHandlers filterhandlers =
|
||||
{
|
||||
CAudioRendererImpl_OnActive, /* pOnActive */
|
||||
CAudioRendererImpl_OnInactive, /* pOnInactive */
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* CAudioRendererPinImpl methods
|
||||
*
|
||||
*/
|
||||
|
||||
static HRESULT CAudioRendererPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
|
||||
{
|
||||
CAudioRendererPinImpl_THIS(pImpl,pin);
|
||||
const WAVEFORMATEX* pwfx;
|
||||
|
||||
TRACE( "(%p,%p)\n",This,pmt );
|
||||
|
||||
if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Audio ) )
|
||||
return E_FAIL;
|
||||
if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_PCM ) )
|
||||
return E_FAIL;
|
||||
if ( !IsEqualGUID( &pmt->formattype, &FORMAT_WaveFormatEx ) )
|
||||
return E_FAIL;
|
||||
if ( pmt->cbFormat < (sizeof(WAVEFORMATEX)-sizeof(WORD)) )
|
||||
return E_FAIL;
|
||||
|
||||
pwfx = (const WAVEFORMATEX*)pmt->pbFormat;
|
||||
if ( pwfx == NULL )
|
||||
return E_FAIL;
|
||||
if ( pwfx->wFormatTag != 1 )
|
||||
return E_FAIL;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT CAudioRendererPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
|
||||
{
|
||||
CAudioRendererPinImpl_THIS(pImpl,pin);
|
||||
HRESULT hr;
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwDataLength;
|
||||
DWORD dwWritten;
|
||||
|
||||
FIXME( "(%p,%p)\n",This,pSample );
|
||||
|
||||
if ( !This->pRender->m_fWaveOutInit )
|
||||
return E_UNEXPECTED;
|
||||
if ( This->pRender->m_fInFlush )
|
||||
return S_FALSE;
|
||||
if ( pSample == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
hr = IMediaSample_GetPointer( pSample, &pData );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
dwDataLength = (DWORD)IMediaSample_GetActualDataLength( pSample );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
TRACE("trying to write %lu bytes\n",dwDataLength);
|
||||
|
||||
ResetEvent( This->pRender->m_hEventRender );
|
||||
hr = CAudioRendererImpl_waveOutWriteData(
|
||||
This->pRender,pData,dwDataLength,&dwWritten);
|
||||
if ( FAILED(hr) )
|
||||
break;
|
||||
if ( hr == S_FALSE )
|
||||
{
|
||||
WaitForSingleObject( This->pRender->m_hEventRender, INFINITE );
|
||||
continue;
|
||||
}
|
||||
pData += dwWritten;
|
||||
dwDataLength -= dwWritten;
|
||||
hr = CAudioRendererImpl_waveOutFlush(This->pRender);
|
||||
if ( FAILED(hr) )
|
||||
break;
|
||||
if ( dwDataLength == 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT CAudioRendererPinImpl_ReceiveCanBlock( CPinBaseImpl* pImpl )
|
||||
{
|
||||
CAudioRendererPinImpl_THIS(pImpl,pin);
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
/* might block. */
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT CAudioRendererPinImpl_EndOfStream( CPinBaseImpl* pImpl )
|
||||
{
|
||||
CAudioRendererPinImpl_THIS(pImpl,pin);
|
||||
|
||||
FIXME( "(%p)\n", This );
|
||||
|
||||
This->pRender->m_fInFlush = FALSE;
|
||||
/* IMediaEventSink::Notify(EC_COMPLETE) */
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT CAudioRendererPinImpl_BeginFlush( CPinBaseImpl* pImpl )
|
||||
{
|
||||
CAudioRendererPinImpl_THIS(pImpl,pin);
|
||||
|
||||
FIXME( "(%p)\n", This );
|
||||
|
||||
This->pRender->m_fInFlush = TRUE;
|
||||
CAudioRendererImpl_waveOutReset(This->pRender);
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT CAudioRendererPinImpl_EndFlush( CPinBaseImpl* pImpl )
|
||||
{
|
||||
CAudioRendererPinImpl_THIS(pImpl,pin);
|
||||
|
||||
FIXME( "(%p)\n", This );
|
||||
|
||||
This->pRender->m_fInFlush = FALSE;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT CAudioRendererPinImpl_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
|
||||
{
|
||||
CAudioRendererPinImpl_THIS(pImpl,pin);
|
||||
|
||||
FIXME( "(%p)\n", This );
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static const CBasePinHandlers pinhandlers =
|
||||
{
|
||||
CAudioRendererPinImpl_CheckMediaType, /* pCheckMediaType */
|
||||
NULL, /* pQualityNotify */
|
||||
CAudioRendererPinImpl_Receive, /* pReceive */
|
||||
CAudioRendererPinImpl_ReceiveCanBlock, /* pReceiveCanBlock */
|
||||
CAudioRendererPinImpl_EndOfStream, /* pEndOfStream */
|
||||
CAudioRendererPinImpl_BeginFlush, /* pBeginFlush */
|
||||
CAudioRendererPinImpl_EndFlush, /* pEndFlush */
|
||||
CAudioRendererPinImpl_NewSegment, /* pNewSegment */
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* new/delete CAudioRendererImpl
|
||||
*
|
||||
*/
|
||||
|
||||
/* can I use offsetof safely? - FIXME? */
|
||||
static QUARTZ_IFEntry FilterIFEntries[] =
|
||||
{
|
||||
{ &IID_IPersist, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
|
||||
{ &IID_IMediaFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
|
||||
{ &IID_IBaseFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
|
||||
{ &IID_IBasicAudio, offsetof(CAudioRendererImpl,basaud)-offsetof(CAudioRendererImpl,unk) },
|
||||
};
|
||||
|
||||
static void QUARTZ_DestroyAudioRenderer(IUnknown* punk)
|
||||
{
|
||||
CAudioRendererImpl_THIS(punk,unk);
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
if ( This->pPin != NULL )
|
||||
{
|
||||
IUnknown_Release(This->pPin->unk.punkControl);
|
||||
This->pPin = NULL;
|
||||
}
|
||||
|
||||
CAudioRendererImpl_UninitIBasicAudio(This);
|
||||
CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
|
||||
}
|
||||
|
||||
HRESULT QUARTZ_CreateAudioRenderer(IUnknown* punkOuter,void** ppobj)
|
||||
{
|
||||
CAudioRendererImpl* This = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n",punkOuter,ppobj);
|
||||
|
||||
This = (CAudioRendererImpl*)
|
||||
QUARTZ_AllocObj( sizeof(CAudioRendererImpl) );
|
||||
if ( This == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
This->pPin = NULL;
|
||||
This->m_fInFlush = FALSE;
|
||||
This->m_fWaveOutInit = FALSE;
|
||||
This->m_hEventRender = (HANDLE)NULL;
|
||||
|
||||
QUARTZ_IUnkInit( &This->unk, punkOuter );
|
||||
|
||||
hr = CBaseFilterImpl_InitIBaseFilter(
|
||||
&This->basefilter,
|
||||
This->unk.punkControl,
|
||||
&CLSID_AudioRender,
|
||||
QUARTZ_AudioRender_Name,
|
||||
&filterhandlers );
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
hr = CAudioRendererImpl_InitIBasicAudio(This);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
|
||||
}
|
||||
}
|
||||
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
QUARTZ_FreeObj(This);
|
||||
return hr;
|
||||
}
|
||||
|
||||
This->unk.pEntries = FilterIFEntries;
|
||||
This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
|
||||
This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRenderer;
|
||||
|
||||
hr = QUARTZ_CreateAudioRendererPin(
|
||||
This,
|
||||
&This->basefilter.csFilter,
|
||||
&This->pPin );
|
||||
if ( SUCCEEDED(hr) )
|
||||
hr = QUARTZ_CompList_AddComp(
|
||||
This->basefilter.pInPins,
|
||||
(IUnknown*)&This->pPin->pin,
|
||||
NULL, 0 );
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
IUnknown_Release( This->unk.punkControl );
|
||||
return hr;
|
||||
}
|
||||
|
||||
*ppobj = (void*)&(This->unk);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* new/delete CAudioRendererPinImpl
|
||||
*
|
||||
*/
|
||||
|
||||
/* can I use offsetof safely? - FIXME? */
|
||||
static QUARTZ_IFEntry PinIFEntries[] =
|
||||
{
|
||||
{ &IID_IPin, offsetof(CAudioRendererPinImpl,pin)-offsetof(CAudioRendererPinImpl,unk) },
|
||||
{ &IID_IMemInputPin, offsetof(CAudioRendererPinImpl,meminput)-offsetof(CAudioRendererPinImpl,unk) },
|
||||
};
|
||||
|
||||
static void QUARTZ_DestroyAudioRendererPin(IUnknown* punk)
|
||||
{
|
||||
CAudioRendererPinImpl_THIS(punk,unk);
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
CPinBaseImpl_UninitIPin( &This->pin );
|
||||
CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
|
||||
}
|
||||
|
||||
HRESULT QUARTZ_CreateAudioRendererPin(
|
||||
CAudioRendererImpl* pFilter,
|
||||
CRITICAL_SECTION* pcsPin,
|
||||
CAudioRendererPinImpl** ppPin)
|
||||
{
|
||||
CAudioRendererPinImpl* This = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
|
||||
|
||||
This = (CAudioRendererPinImpl*)
|
||||
QUARTZ_AllocObj( sizeof(CAudioRendererPinImpl) );
|
||||
if ( This == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
QUARTZ_IUnkInit( &This->unk, NULL );
|
||||
This->pRender = pFilter;
|
||||
|
||||
hr = CPinBaseImpl_InitIPin(
|
||||
&This->pin,
|
||||
This->unk.punkControl,
|
||||
pcsPin,
|
||||
&pFilter->basefilter,
|
||||
QUARTZ_AudioRenderPin_Name,
|
||||
FALSE,
|
||||
&pinhandlers );
|
||||
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
hr = CMemInputPinBaseImpl_InitIMemInputPin(
|
||||
&This->meminput,
|
||||
This->unk.punkControl,
|
||||
&This->pin );
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
CPinBaseImpl_UninitIPin( &This->pin );
|
||||
}
|
||||
}
|
||||
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
QUARTZ_FreeObj(This);
|
||||
return hr;
|
||||
}
|
||||
|
||||
This->unk.pEntries = PinIFEntries;
|
||||
This->unk.dwEntries = sizeof(PinIFEntries)/sizeof(PinIFEntries[0]);
|
||||
This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRendererPin;
|
||||
|
||||
*ppPin = This;
|
||||
|
||||
TRACE("returned successfully.\n");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* CAudioRendererImpl::IBasicAudio
|
||||
*
|
||||
*/
|
||||
|
||||
static HRESULT WINAPI
|
||||
IBasicAudio_fnQueryInterface(IBasicAudio* iface,REFIID riid,void** ppobj)
|
||||
{
|
||||
CAudioRendererImpl_THIS(iface,basaud);
|
||||
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
IBasicAudio_fnAddRef(IBasicAudio* iface)
|
||||
{
|
||||
CAudioRendererImpl_THIS(iface,basaud);
|
||||
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
return IUnknown_AddRef(This->unk.punkControl);
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
IBasicAudio_fnRelease(IBasicAudio* iface)
|
||||
{
|
||||
CAudioRendererImpl_THIS(iface,basaud);
|
||||
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
return IUnknown_Release(This->unk.punkControl);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
IBasicAudio_fnGetTypeInfoCount(IBasicAudio* iface,UINT* pcTypeInfo)
|
||||
{
|
||||
CAudioRendererImpl_THIS(iface,basaud);
|
||||
|
||||
FIXME("(%p)->()\n",This);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
IBasicAudio_fnGetTypeInfo(IBasicAudio* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
|
||||
{
|
||||
CAudioRendererImpl_THIS(iface,basaud);
|
||||
|
||||
FIXME("(%p)->()\n",This);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
IBasicAudio_fnGetIDsOfNames(IBasicAudio* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
|
||||
{
|
||||
CAudioRendererImpl_THIS(iface,basaud);
|
||||
|
||||
FIXME("(%p)->()\n",This);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
IBasicAudio_fnInvoke(IBasicAudio* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
|
||||
{
|
||||
CAudioRendererImpl_THIS(iface,basaud);
|
||||
|
||||
FIXME("(%p)->()\n",This);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI
|
||||
IBasicAudio_fnput_Volume(IBasicAudio* iface,long lVol)
|
||||
{
|
||||
CAudioRendererImpl_THIS(iface,basaud);
|
||||
|
||||
FIXME("(%p)->()\n",This);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol)
|
||||
{
|
||||
CAudioRendererImpl_THIS(iface,basaud);
|
||||
|
||||
FIXME("(%p)->()\n",This);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance)
|
||||
{
|
||||
CAudioRendererImpl_THIS(iface,basaud);
|
||||
|
||||
FIXME("(%p)->()\n",This);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance)
|
||||
{
|
||||
CAudioRendererImpl_THIS(iface,basaud);
|
||||
|
||||
FIXME("(%p)->()\n",This);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
static ICOM_VTABLE(IBasicAudio) ibasicaudio =
|
||||
{
|
||||
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
||||
/* IUnknown fields */
|
||||
IBasicAudio_fnQueryInterface,
|
||||
IBasicAudio_fnAddRef,
|
||||
IBasicAudio_fnRelease,
|
||||
/* IDispatch fields */
|
||||
IBasicAudio_fnGetTypeInfoCount,
|
||||
IBasicAudio_fnGetTypeInfo,
|
||||
IBasicAudio_fnGetIDsOfNames,
|
||||
IBasicAudio_fnInvoke,
|
||||
/* IBasicAudio fields */
|
||||
IBasicAudio_fnput_Volume,
|
||||
IBasicAudio_fnget_Volume,
|
||||
IBasicAudio_fnput_Balance,
|
||||
IBasicAudio_fnget_Balance,
|
||||
};
|
||||
|
||||
|
||||
HRESULT CAudioRendererImpl_InitIBasicAudio( CAudioRendererImpl* This )
|
||||
{
|
||||
TRACE("(%p)\n",This);
|
||||
ICOM_VTBL(&This->basaud) = &ibasicaudio;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
void CAudioRendererImpl_UninitIBasicAudio( CAudioRendererImpl* This )
|
||||
{
|
||||
TRACE("(%p)\n",This);
|
||||
}
|
||||
|
70
dlls/quartz/audren.h
Normal file
70
dlls/quartz/audren.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Audio Renderer (CLSID_AudioRender)
|
||||
*
|
||||
* FIXME
|
||||
* - implements IRefereneceClock.
|
||||
*
|
||||
* hidenori@a2.ctktv.ne.jp
|
||||
*/
|
||||
|
||||
#ifndef WINE_DSHOW_AUDREN_H
|
||||
#define WINE_DSHOW_AUDREN_H
|
||||
|
||||
#include "iunk.h"
|
||||
#include "basefilt.h"
|
||||
|
||||
#define WINE_QUARTZ_WAVEOUT_COUNT 4
|
||||
|
||||
typedef struct CAudioRendererImpl CAudioRendererImpl;
|
||||
typedef struct CAudioRendererPinImpl CAudioRendererPinImpl;
|
||||
|
||||
|
||||
typedef struct AudRen_IBasicAudioImpl
|
||||
{
|
||||
ICOM_VFIELD(IBasicAudio);
|
||||
} AudRen_IBasicAudioImpl;
|
||||
|
||||
struct CAudioRendererImpl
|
||||
{
|
||||
QUARTZ_IUnkImpl unk;
|
||||
CBaseFilterImpl basefilter;
|
||||
AudRen_IBasicAudioImpl basaud;
|
||||
|
||||
CAudioRendererPinImpl* pPin;
|
||||
|
||||
BOOL m_fInFlush;
|
||||
|
||||
/* for waveOut */
|
||||
BOOL m_fWaveOutInit;
|
||||
HANDLE m_hEventRender;
|
||||
HWAVEOUT m_hWaveOut;
|
||||
DWORD m_dwBlockSize;
|
||||
WAVEHDR* m_phdrCur;
|
||||
WAVEHDR m_hdr[WINE_QUARTZ_WAVEOUT_COUNT];
|
||||
};
|
||||
|
||||
struct CAudioRendererPinImpl
|
||||
{
|
||||
QUARTZ_IUnkImpl unk;
|
||||
CPinBaseImpl pin;
|
||||
CMemInputPinBaseImpl meminput;
|
||||
|
||||
CAudioRendererImpl* pRender;
|
||||
};
|
||||
|
||||
#define CAudioRendererImpl_THIS(iface,member) CAudioRendererImpl* This = ((CAudioRendererImpl*)(((char*)iface)-offsetof(CAudioRendererImpl,member)))
|
||||
#define CAudioRendererPinImpl_THIS(iface,member) CAudioRendererPinImpl* This = ((CAudioRendererPinImpl*)(((char*)iface)-offsetof(CAudioRendererPinImpl,member)))
|
||||
|
||||
|
||||
HRESULT CAudioRendererImpl_InitIBasicAudio( CAudioRendererImpl* This );
|
||||
void CAudioRendererImpl_UninitIBasicAudio( CAudioRendererImpl* This );
|
||||
|
||||
HRESULT QUARTZ_CreateAudioRenderer(IUnknown* punkOuter,void** ppobj);
|
||||
HRESULT QUARTZ_CreateAudioRendererPin(
|
||||
CAudioRendererImpl* pFilter,
|
||||
CRITICAL_SECTION* pcsPin,
|
||||
CAudioRendererPinImpl** ppPin);
|
||||
|
||||
|
||||
|
||||
#endif /* WINE_DSHOW_AUDREN_H */
|
@ -73,54 +73,81 @@ static HRESULT WINAPI
|
||||
CBaseFilterImpl_fnStop(IBaseFilter* iface)
|
||||
{
|
||||
ICOM_THIS(CBaseFilterImpl,iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
hr = NOERROR;
|
||||
|
||||
EnterCriticalSection( &This->csFilter );
|
||||
|
||||
/* FIXME - call OnStop() */
|
||||
if ( This->fstate == State_Running )
|
||||
{
|
||||
if ( This->pHandlers->pOnInactive != NULL )
|
||||
hr = This->pHandlers->pOnInactive( This );
|
||||
}
|
||||
|
||||
This->fstate = State_Stopped;
|
||||
if ( SUCCEEDED(hr) )
|
||||
This->fstate = State_Stopped;
|
||||
LeaveCriticalSection( &This->csFilter );
|
||||
|
||||
return NOERROR;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
CBaseFilterImpl_fnPause(IBaseFilter* iface)
|
||||
{
|
||||
ICOM_THIS(CBaseFilterImpl,iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
hr = NOERROR;
|
||||
|
||||
EnterCriticalSection( &This->csFilter );
|
||||
|
||||
/* FIXME - call OnPause() */
|
||||
if ( This->fstate == State_Running )
|
||||
{
|
||||
if ( This->pHandlers->pOnInactive != NULL )
|
||||
hr = This->pHandlers->pOnInactive( This );
|
||||
}
|
||||
|
||||
This->fstate = State_Paused;
|
||||
if ( SUCCEEDED(hr) )
|
||||
This->fstate = State_Paused;
|
||||
|
||||
LeaveCriticalSection( &This->csFilter );
|
||||
|
||||
return NOERROR;
|
||||
TRACE("hr = %08lx\n",hr);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
CBaseFilterImpl_fnRun(IBaseFilter* iface,REFERENCE_TIME rtStart)
|
||||
{
|
||||
ICOM_THIS(CBaseFilterImpl,iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
hr = NOERROR;
|
||||
|
||||
EnterCriticalSection( &This->csFilter );
|
||||
|
||||
/* FIXME - call OnRun() */
|
||||
|
||||
This->rtStart = rtStart;
|
||||
This->fstate = State_Running;
|
||||
|
||||
if ( This->fstate != State_Running )
|
||||
{
|
||||
if ( This->pHandlers->pOnActive != NULL )
|
||||
hr = This->pHandlers->pOnActive( This );
|
||||
}
|
||||
|
||||
if ( SUCCEEDED(hr) )
|
||||
This->fstate = State_Running;
|
||||
|
||||
LeaveCriticalSection( &This->csFilter );
|
||||
|
||||
return NOERROR;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -136,6 +163,7 @@ CBaseFilterImpl_fnGetState(IBaseFilter* iface,DWORD dw,FILTER_STATE* pState)
|
||||
/* FIXME - ignore 'intermediate state' now */
|
||||
|
||||
EnterCriticalSection( &This->csFilter );
|
||||
TRACE("state %d\n",This->fstate);
|
||||
*pState = This->fstate;
|
||||
LeaveCriticalSection( &This->csFilter );
|
||||
|
||||
@ -366,7 +394,8 @@ static ICOM_VTABLE(IBaseFilter) ibasefilter =
|
||||
|
||||
HRESULT CBaseFilterImpl_InitIBaseFilter(
|
||||
CBaseFilterImpl* This, IUnknown* punkControl,
|
||||
const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph )
|
||||
const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph,
|
||||
const CBaseFilterHandlers* pHandlers )
|
||||
{
|
||||
TRACE("(%p,%p)\n",This,punkControl);
|
||||
|
||||
@ -378,6 +407,7 @@ HRESULT CBaseFilterImpl_InitIBaseFilter(
|
||||
|
||||
ICOM_VTBL(This) = &ibasefilter;
|
||||
This->punkControl = punkControl;
|
||||
This->pHandlers = pHandlers;
|
||||
This->pclsidFilter = pclsidFilter;
|
||||
This->pInPins = NULL;
|
||||
This->pOutPins = NULL;
|
||||
@ -394,6 +424,18 @@ HRESULT CBaseFilterImpl_InitIBaseFilter(
|
||||
return E_OUTOFMEMORY;
|
||||
memcpy( This->pwszNameGraph, lpwszNameGraph, This->cbNameGraph );
|
||||
|
||||
This->pInPins = QUARTZ_CompList_Alloc();
|
||||
This->pOutPins = QUARTZ_CompList_Alloc();
|
||||
if ( This->pInPins == NULL || This->pOutPins == NULL )
|
||||
{
|
||||
if ( This->pInPins != NULL )
|
||||
QUARTZ_CompList_Free(This->pInPins);
|
||||
if ( This->pOutPins != NULL )
|
||||
QUARTZ_CompList_Free(This->pOutPins);
|
||||
QUARTZ_FreeMem(This->pwszNameGraph);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
InitializeCriticalSection( &This->csFilter );
|
||||
|
||||
return NOERROR;
|
||||
@ -415,7 +457,6 @@ void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This )
|
||||
break;
|
||||
pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
|
||||
QUARTZ_CompList_RemoveComp( This->pInPins, (IUnknown*)pPin );
|
||||
IPin_Release( pPin );
|
||||
}
|
||||
|
||||
QUARTZ_CompList_Free( This->pInPins );
|
||||
@ -430,7 +471,6 @@ void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This )
|
||||
break;
|
||||
pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
|
||||
QUARTZ_CompList_RemoveComp( This->pOutPins, (IUnknown*)pPin );
|
||||
IPin_Release( pPin );
|
||||
}
|
||||
|
||||
QUARTZ_CompList_Free( This->pOutPins );
|
||||
|
@ -14,13 +14,20 @@
|
||||
*/
|
||||
|
||||
#include "complist.h"
|
||||
#include "mtype.h"
|
||||
|
||||
typedef struct CBaseFilterHandlers CBaseFilterHandlers;
|
||||
typedef struct CBasePinHandlers CBasePinHandlers;
|
||||
|
||||
typedef struct CBaseFilterImpl
|
||||
{
|
||||
/* IPersist - IMediaFilter - IBaseFilter */
|
||||
ICOM_VFIELD(IBaseFilter);
|
||||
|
||||
/* IUnknown fields */
|
||||
IUnknown* punkControl;
|
||||
/* IBaseFilter fields */
|
||||
const CBaseFilterHandlers* pHandlers;
|
||||
CRITICAL_SECTION csFilter;
|
||||
const CLSID* pclsidFilter;
|
||||
QUARTZ_CompList* pInPins; /* a list of IPin-s. */
|
||||
@ -33,30 +40,44 @@ typedef struct CBaseFilterImpl
|
||||
FILTER_STATE fstate;
|
||||
} CBaseFilterImpl;
|
||||
|
||||
struct CBaseFilterHandlers
|
||||
{
|
||||
HRESULT (*pOnActive)( CBaseFilterImpl* pImpl );
|
||||
HRESULT (*pOnInactive)( CBaseFilterImpl* pImpl );
|
||||
};
|
||||
|
||||
|
||||
HRESULT CBaseFilterImpl_InitIBaseFilter(
|
||||
CBaseFilterImpl* This, IUnknown* punkControl,
|
||||
const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph );
|
||||
const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph,
|
||||
const CBaseFilterHandlers* pHandlers );
|
||||
void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This );
|
||||
|
||||
|
||||
/*
|
||||
* Implements IPin and IMemInputPin. (internal)
|
||||
* Implements IPin, IMemInputPin, and IQualityControl. (internal)
|
||||
*
|
||||
* a base class for implementing IPin.
|
||||
*/
|
||||
|
||||
typedef struct CPinBaseImpl
|
||||
{
|
||||
/* IPin */
|
||||
ICOM_VFIELD(IPin);
|
||||
|
||||
/* IUnknown fields */
|
||||
IUnknown* punkControl;
|
||||
/* IPin fields */
|
||||
const CBasePinHandlers* pHandlers;
|
||||
DWORD cbIdLen;
|
||||
WCHAR* pwszId;
|
||||
BOOL bOutput;
|
||||
|
||||
CRITICAL_SECTION csPin;
|
||||
/* you can change AcceptTypes while pcsPin has been hold */
|
||||
const AM_MEDIA_TYPE* pmtAcceptTypes;
|
||||
ULONG cAcceptTypes;
|
||||
|
||||
CRITICAL_SECTION* pcsPin;
|
||||
CBaseFilterImpl* pFilter;
|
||||
IPin* pPinConnectedTo;
|
||||
AM_MEDIA_TYPE* pmtConn;
|
||||
@ -64,31 +85,66 @@ typedef struct CPinBaseImpl
|
||||
|
||||
typedef struct CMemInputPinBaseImpl
|
||||
{
|
||||
/* IMemInputPin */
|
||||
ICOM_VFIELD(IMemInputPin);
|
||||
|
||||
/* IUnknown fields */
|
||||
IUnknown* punkControl;
|
||||
/* IMemInputPin fields */
|
||||
CRITICAL_SECTION* pcsPin;
|
||||
CPinBaseImpl* pPin;
|
||||
IMemAllocator* pAllocator;
|
||||
BOOL bReadonly;
|
||||
} CMemInputPinBaseImpl;
|
||||
|
||||
typedef struct CQualityControlPassThruImpl
|
||||
{
|
||||
/* IQualityControl */
|
||||
ICOM_VFIELD(IQualityControl);
|
||||
|
||||
/* IUnknown fields */
|
||||
IUnknown* punkControl;
|
||||
/* IQualityControl fields */
|
||||
CPinBaseImpl* pPin;
|
||||
IQualityControl* pControl;
|
||||
} CQualityControlPassThruImpl;
|
||||
|
||||
|
||||
struct CBasePinHandlers
|
||||
{
|
||||
HRESULT (*pCheckMediaType)( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt );
|
||||
HRESULT (*pQualityNotify)( CPinBaseImpl* pImpl, IBaseFilter* pFilter, Quality q );
|
||||
HRESULT (*pReceive)( CPinBaseImpl* pImpl, IMediaSample* pSample );
|
||||
HRESULT (*pReceiveCanBlock)( CPinBaseImpl* pImpl );
|
||||
HRESULT (*pEndOfStream)( CPinBaseImpl* pImpl );
|
||||
HRESULT (*pBeginFlush)( CPinBaseImpl* pImpl );
|
||||
HRESULT (*pEndFlush)( CPinBaseImpl* pImpl );
|
||||
HRESULT (*pNewSegment)( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate );
|
||||
};
|
||||
|
||||
|
||||
|
||||
HRESULT CPinBaseImpl_InitIPin(
|
||||
CPinBaseImpl* This, IUnknown* punkControl,
|
||||
CRITICAL_SECTION* pcsPin,
|
||||
CBaseFilterImpl* pFilter, LPCWSTR pwszId,
|
||||
BOOL bOutput );
|
||||
BOOL bOutput,
|
||||
const CBasePinHandlers* pHandlers );
|
||||
void CPinBaseImpl_UninitIPin( CPinBaseImpl* This );
|
||||
|
||||
|
||||
HRESULT CMemInputPinBaseImpl_InitIMemInputPin(
|
||||
CMemInputPinBaseImpl* This, IUnknown* punkControl,
|
||||
CRITICAL_SECTION* pcsPin
|
||||
);
|
||||
CPinBaseImpl* pPin );
|
||||
void CMemInputPinBaseImpl_UninitIMemInputPin(
|
||||
CMemInputPinBaseImpl* This );
|
||||
|
||||
|
||||
HRESULT CQualityControlPassThruImpl_InitIQualityControl(
|
||||
CQualityControlPassThruImpl* This, IUnknown* punkControl,
|
||||
CPinBaseImpl* pPin );
|
||||
void CQualityControlPassThruImpl_UninitIQualityControl(
|
||||
CQualityControlPassThruImpl* This );
|
||||
|
||||
|
||||
|
||||
#endif /* WINE_DSHOW_BASEFILT_H */
|
||||
|
@ -21,7 +21,6 @@ DEFAULT_DEBUG_CHANNEL(quartz);
|
||||
|
||||
#include "quartz_private.h"
|
||||
#include "basefilt.h"
|
||||
#include "mtype.h"
|
||||
#include "memalloc.h"
|
||||
|
||||
|
||||
@ -66,6 +65,7 @@ CPinBaseImpl_fnConnect(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
|
||||
{
|
||||
ICOM_THIS(CPinBaseImpl,iface);
|
||||
HRESULT hr = E_NOTIMPL;
|
||||
ULONG i;
|
||||
|
||||
FIXME("(%p)->(%p,%p) stub!\n",This,pPin,pmt);
|
||||
|
||||
@ -74,7 +74,7 @@ CPinBaseImpl_fnConnect(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
|
||||
if ( pPin == NULL || pmt == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection( &This->csPin );
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
|
||||
if ( This->pPinConnectedTo != NULL )
|
||||
{
|
||||
@ -84,11 +84,52 @@ CPinBaseImpl_fnConnect(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
|
||||
|
||||
/* FIXME - return fail if running */
|
||||
|
||||
/* FIXME */
|
||||
if ( pmt != NULL )
|
||||
{
|
||||
hr = IPin_QueryAccept(iface,pmt);
|
||||
if ( FAILED(hr) )
|
||||
goto err;
|
||||
hr = IPin_ReceiveConnection(pPin,iface,pmt);
|
||||
if ( FAILED(hr) )
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < This->cAcceptTypes; i++ )
|
||||
{
|
||||
pmt = &This->pmtAcceptTypes[i];
|
||||
hr = IPin_QueryAccept(iface,pmt);
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
hr = IPin_ReceiveConnection(pPin,iface,pmt);
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
goto connected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr = VFW_E_TYPE_NOT_ACCEPTED;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ( FAILED(hr) )
|
||||
goto err;
|
||||
|
||||
connected:;
|
||||
This->pmtConn = QUARTZ_MediaType_Duplicate( pmt );
|
||||
if ( This->pmtConn == NULL )
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
IPin_Disconnect(pPin);
|
||||
goto err;
|
||||
}
|
||||
hr = S_OK;
|
||||
|
||||
This->pPinConnectedTo = pPin; IPin_AddRef(pPin);
|
||||
|
||||
hr = E_NOTIMPL;
|
||||
err:
|
||||
LeaveCriticalSection( &This->csPin );
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
@ -106,7 +147,7 @@ CPinBaseImpl_fnReceiveConnection(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt
|
||||
if ( pPin == NULL || pmt == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection( &This->csPin );
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
|
||||
if ( This->pPinConnectedTo != NULL )
|
||||
{
|
||||
@ -116,13 +157,24 @@ CPinBaseImpl_fnReceiveConnection(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt
|
||||
|
||||
/* FIXME - return fail if running */
|
||||
|
||||
/* FIXME */
|
||||
|
||||
hr = E_NOTIMPL;
|
||||
hr = IPin_QueryAccept(iface,pmt);
|
||||
if ( FAILED(hr) )
|
||||
goto err;
|
||||
|
||||
This->pmtConn = QUARTZ_MediaType_Duplicate( pmt );
|
||||
if ( This->pmtConn == NULL )
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto err;
|
||||
}
|
||||
hr = S_OK;
|
||||
|
||||
This->pPinConnectedTo = pPin; IPin_AddRef(pPin);
|
||||
err:
|
||||
LeaveCriticalSection( &This->csPin );
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return E_NOTIMPL;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -133,7 +185,7 @@ CPinBaseImpl_fnDisconnect(IPin* iface)
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
|
||||
EnterCriticalSection( &This->csPin );
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
|
||||
/* FIXME - return fail if running */
|
||||
|
||||
@ -156,7 +208,7 @@ CPinBaseImpl_fnDisconnect(IPin* iface)
|
||||
hr = S_FALSE; /* FIXME - is this correct??? */
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &This->csPin );
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
@ -172,7 +224,7 @@ CPinBaseImpl_fnConnectedTo(IPin* iface,IPin** ppPin)
|
||||
if ( ppPin == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection( &This->csPin );
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
|
||||
*ppPin = This->pPinConnectedTo;
|
||||
if ( This->pPinConnectedTo != NULL )
|
||||
@ -181,7 +233,7 @@ CPinBaseImpl_fnConnectedTo(IPin* iface,IPin** ppPin)
|
||||
hr = NOERROR;
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &This->csPin );
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
@ -197,7 +249,7 @@ CPinBaseImpl_fnConnectionMediaType(IPin* iface,AM_MEDIA_TYPE* pmt)
|
||||
if ( pmt == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection( &This->csPin );
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
|
||||
if ( This->pmtConn != NULL )
|
||||
{
|
||||
@ -211,7 +263,7 @@ CPinBaseImpl_fnConnectionMediaType(IPin* iface,AM_MEDIA_TYPE* pmt)
|
||||
hr = NOERROR;
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &This->csPin );
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
@ -226,7 +278,7 @@ CPinBaseImpl_fnQueryPinInfo(IPin* iface,PIN_INFO* pinfo)
|
||||
if ( pinfo == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection( &This->csPin );
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
|
||||
ZeroMemory( pinfo, sizeof(PIN_INFO) );
|
||||
pinfo->pFilter = (IBaseFilter*)(This->pFilter);
|
||||
@ -241,7 +293,7 @@ CPinBaseImpl_fnQueryPinInfo(IPin* iface,PIN_INFO* pinfo)
|
||||
pinfo->achName[sizeof(pinfo->achName)/sizeof(pinfo->achName[0])-1] = 0;
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &This->csPin );
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
@ -283,20 +335,42 @@ static HRESULT WINAPI
|
||||
CPinBaseImpl_fnQueryAccept(IPin* iface,const AM_MEDIA_TYPE* pmt)
|
||||
{
|
||||
ICOM_THIS(CPinBaseImpl,iface);
|
||||
HRESULT hr;
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->(%p)\n",This,pmt);
|
||||
|
||||
return E_NOTIMPL;
|
||||
if ( pmt == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
hr = NOERROR;
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
if ( This->pHandlers->pCheckMediaType != NULL )
|
||||
hr = This->pHandlers->pCheckMediaType(This,pmt);
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
CPinBaseImpl_fnEnumMediaTypes(IPin* iface,IEnumMediaTypes** ppenum)
|
||||
{
|
||||
ICOM_THIS(CPinBaseImpl,iface);
|
||||
HRESULT hr;
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->(%p)\n",This,ppenum);
|
||||
|
||||
return E_NOTIMPL;
|
||||
if ( ppenum == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
hr = E_NOTIMPL;
|
||||
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
if ( This->cAcceptTypes > 0 )
|
||||
hr = QUARTZ_CreateEnumMediaTypes(
|
||||
ppenum, This->pmtAcceptTypes, This->cAcceptTypes );
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -314,52 +388,76 @@ static HRESULT WINAPI
|
||||
CPinBaseImpl_fnEndOfStream(IPin* iface)
|
||||
{
|
||||
ICOM_THIS(CPinBaseImpl,iface);
|
||||
HRESULT hr = E_NOTIMPL;
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
if ( This->bOutput )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return E_NOTIMPL;
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
if ( This->pHandlers->pEndOfStream != NULL )
|
||||
hr = This->pHandlers->pEndOfStream(This);
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
CPinBaseImpl_fnBeginFlush(IPin* iface)
|
||||
{
|
||||
ICOM_THIS(CPinBaseImpl,iface);
|
||||
HRESULT hr = E_NOTIMPL;
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
if ( This->bOutput )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return E_NOTIMPL;
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
if ( This->pHandlers->pBeginFlush != NULL )
|
||||
hr = This->pHandlers->pBeginFlush(This);
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
CPinBaseImpl_fnEndFlush(IPin* iface)
|
||||
{
|
||||
ICOM_THIS(CPinBaseImpl,iface);
|
||||
HRESULT hr = E_NOTIMPL;
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
if ( This->bOutput )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return E_NOTIMPL;
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
if ( This->pHandlers->pEndFlush != NULL )
|
||||
hr = This->pHandlers->pEndFlush(This);
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
CPinBaseImpl_fnNewSegment(IPin* iface,REFERENCE_TIME rtStart,REFERENCE_TIME rtStop,double rate)
|
||||
{
|
||||
ICOM_THIS(CPinBaseImpl,iface);
|
||||
HRESULT hr = E_NOTIMPL;
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
if ( This->bOutput )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return E_NOTIMPL;
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
if ( This->pHandlers->pNewSegment != NULL )
|
||||
hr = This->pHandlers->pNewSegment(This,rtStart,rtStop,rate);
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
@ -393,8 +491,10 @@ static ICOM_VTABLE(IPin) ipin =
|
||||
|
||||
HRESULT CPinBaseImpl_InitIPin(
|
||||
CPinBaseImpl* This, IUnknown* punkControl,
|
||||
CRITICAL_SECTION* pcsPin,
|
||||
CBaseFilterImpl* pFilter, LPCWSTR pwszId,
|
||||
BOOL bOutput )
|
||||
BOOL bOutput,
|
||||
const CBasePinHandlers* pHandlers )
|
||||
{
|
||||
HRESULT hr = NOERROR;
|
||||
|
||||
@ -408,9 +508,13 @@ HRESULT CPinBaseImpl_InitIPin(
|
||||
|
||||
ICOM_VTBL(This) = &ipin;
|
||||
This->punkControl = punkControl;
|
||||
This->pHandlers = pHandlers;
|
||||
This->cbIdLen = sizeof(WCHAR)*(strlenW(pwszId)+1);
|
||||
This->pwszId = NULL;
|
||||
This->bOutput = bOutput;
|
||||
This->pmtAcceptTypes = NULL;
|
||||
This->cAcceptTypes = 0;
|
||||
This->pcsPin = pcsPin;
|
||||
This->pFilter = pFilter;
|
||||
This->pPinConnectedTo = NULL;
|
||||
This->pmtConn = NULL;
|
||||
@ -421,8 +525,7 @@ HRESULT CPinBaseImpl_InitIPin(
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
InitializeCriticalSection( &This->csPin );
|
||||
memcpy( This->pwszId, pwszId, This->cbIdLen );
|
||||
|
||||
return NOERROR;
|
||||
|
||||
@ -442,8 +545,6 @@ void CPinBaseImpl_UninitIPin( CPinBaseImpl* This )
|
||||
QUARTZ_FreeMem( This->pwszId );
|
||||
This->pwszId = NULL;
|
||||
}
|
||||
|
||||
DeleteCriticalSection( &This->csPin );
|
||||
}
|
||||
|
||||
|
||||
@ -497,7 +598,7 @@ CMemInputPinBaseImpl_fnGetAllocator(IMemInputPin* iface,IMemAllocator** ppAlloca
|
||||
if ( ppAllocator == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
EnterCriticalSection( This->pPin->pcsPin );
|
||||
|
||||
if ( This->pAllocator == NULL )
|
||||
{
|
||||
@ -516,7 +617,7 @@ CMemInputPinBaseImpl_fnGetAllocator(IMemInputPin* iface,IMemAllocator** ppAlloca
|
||||
IMemAllocator_AddRef(This->pAllocator);
|
||||
}
|
||||
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
LeaveCriticalSection( This->pPin->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
@ -531,7 +632,7 @@ CMemInputPinBaseImpl_fnNotifyAllocator(IMemInputPin* iface,IMemAllocator* pAlloc
|
||||
if ( pAllocator == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
EnterCriticalSection( This->pPin->pcsPin );
|
||||
|
||||
if ( This->pAllocator != NULL )
|
||||
{
|
||||
@ -543,7 +644,7 @@ CMemInputPinBaseImpl_fnNotifyAllocator(IMemInputPin* iface,IMemAllocator* pAlloc
|
||||
|
||||
This->bReadonly = bReadonly;
|
||||
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
LeaveCriticalSection( This->pPin->pcsPin );
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
@ -566,10 +667,16 @@ static HRESULT WINAPI
|
||||
CMemInputPinBaseImpl_fnReceive(IMemInputPin* iface,IMediaSample* pSample)
|
||||
{
|
||||
ICOM_THIS(CMemInputPinBaseImpl,iface);
|
||||
HRESULT hr = E_NOTIMPL;
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->(%p)\n",This,pSample);
|
||||
|
||||
return E_NOTIMPL;
|
||||
EnterCriticalSection( This->pPin->pcsPin );
|
||||
if ( This->pPin->pHandlers->pReceive != NULL )
|
||||
hr = This->pPin->pHandlers->pReceive(This->pPin,pSample);
|
||||
LeaveCriticalSection( This->pPin->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -584,7 +691,7 @@ CMemInputPinBaseImpl_fnReceiveMultiple(IMemInputPin* iface,IMediaSample** ppSamp
|
||||
if ( ppSample == NULL || pnSampleProcessed == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection( This->pcsPin );
|
||||
EnterCriticalSection( This->pPin->pcsPin );
|
||||
|
||||
hr = NOERROR;
|
||||
for ( n = 0; n < nSample; n++ )
|
||||
@ -594,7 +701,7 @@ CMemInputPinBaseImpl_fnReceiveMultiple(IMemInputPin* iface,IMediaSample** ppSamp
|
||||
break;
|
||||
}
|
||||
|
||||
LeaveCriticalSection( This->pcsPin );
|
||||
LeaveCriticalSection( This->pPin->pcsPin );
|
||||
|
||||
*pnSampleProcessed = n;
|
||||
return hr;
|
||||
@ -604,10 +711,16 @@ static HRESULT WINAPI
|
||||
CMemInputPinBaseImpl_fnReceiveCanBlock(IMemInputPin* iface)
|
||||
{
|
||||
ICOM_THIS(CMemInputPinBaseImpl,iface);
|
||||
HRESULT hr = E_NOTIMPL;
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
return E_NOTIMPL;
|
||||
EnterCriticalSection( This->pPin->pcsPin );
|
||||
if ( This->pPin->pHandlers->pReceiveCanBlock != NULL )
|
||||
hr = This->pPin->pHandlers->pReceiveCanBlock(This->pPin);
|
||||
LeaveCriticalSection( This->pPin->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
@ -629,8 +742,7 @@ static ICOM_VTABLE(IMemInputPin) imeminputpin =
|
||||
|
||||
HRESULT CMemInputPinBaseImpl_InitIMemInputPin(
|
||||
CMemInputPinBaseImpl* This, IUnknown* punkControl,
|
||||
CRITICAL_SECTION* pcsPin
|
||||
)
|
||||
CPinBaseImpl* pPin )
|
||||
{
|
||||
TRACE("(%p,%p)\n",This,punkControl);
|
||||
|
||||
@ -642,7 +754,7 @@ HRESULT CMemInputPinBaseImpl_InitIMemInputPin(
|
||||
|
||||
ICOM_VTBL(This) = &imeminputpin;
|
||||
This->punkControl = punkControl;
|
||||
This->pcsPin = pcsPin;
|
||||
This->pPin = pPin;
|
||||
This->pAllocator = NULL;
|
||||
This->bReadonly = FALSE;
|
||||
|
||||
@ -661,4 +773,107 @@ void CMemInputPinBaseImpl_UninitIMemInputPin(
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* CQualityControlPassThruImpl
|
||||
*
|
||||
*/
|
||||
|
||||
static HRESULT WINAPI
|
||||
CQualityControlPassThruImpl_fnQueryInterface(IQualityControl* iface,REFIID riid,void** ppobj)
|
||||
{
|
||||
ICOM_THIS(CQualityControlPassThruImpl,iface);
|
||||
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
return IUnknown_QueryInterface(This->punkControl,riid,ppobj);
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
CQualityControlPassThruImpl_fnAddRef(IQualityControl* iface)
|
||||
{
|
||||
ICOM_THIS(CQualityControlPassThruImpl,iface);
|
||||
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
return IUnknown_AddRef(This->punkControl);
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
CQualityControlPassThruImpl_fnRelease(IQualityControl* iface)
|
||||
{
|
||||
ICOM_THIS(CQualityControlPassThruImpl,iface);
|
||||
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
return IUnknown_Release(This->punkControl);
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI
|
||||
CQualityControlPassThruImpl_fnNotify(IQualityControl* iface,IBaseFilter* pFilter,Quality q)
|
||||
{
|
||||
ICOM_THIS(CQualityControlPassThruImpl,iface);
|
||||
HRESULT hr = S_FALSE;
|
||||
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
if ( This->pControl != NULL )
|
||||
return IQualityControl_Notify( This->pControl, pFilter, q );
|
||||
|
||||
EnterCriticalSection( This->pPin->pcsPin );
|
||||
if ( This->pPin->pHandlers->pQualityNotify != NULL )
|
||||
hr = This->pPin->pHandlers->pQualityNotify(This->pPin,pFilter,q);
|
||||
LeaveCriticalSection( This->pPin->pcsPin );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
CQualityControlPassThruImpl_fnSetSink(IQualityControl* iface,IQualityControl* pControl)
|
||||
{
|
||||
ICOM_THIS(CQualityControlPassThruImpl,iface);
|
||||
|
||||
TRACE("(%p)->()\n",This);
|
||||
|
||||
This->pControl = pControl; /* AddRef() must not be called */
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static ICOM_VTABLE(IQualityControl) iqualitycontrol =
|
||||
{
|
||||
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
||||
/* IUnknown fields */
|
||||
CQualityControlPassThruImpl_fnQueryInterface,
|
||||
CQualityControlPassThruImpl_fnAddRef,
|
||||
CQualityControlPassThruImpl_fnRelease,
|
||||
/* IQualityControl fields */
|
||||
CQualityControlPassThruImpl_fnNotify,
|
||||
CQualityControlPassThruImpl_fnSetSink,
|
||||
};
|
||||
|
||||
HRESULT CQualityControlPassThruImpl_InitIQualityControl(
|
||||
CQualityControlPassThruImpl* This, IUnknown* punkControl,
|
||||
CPinBaseImpl* pPin )
|
||||
{
|
||||
TRACE("(%p,%p)\n",This,punkControl);
|
||||
|
||||
if ( punkControl == NULL )
|
||||
{
|
||||
ERR( "punkControl must not be NULL\n" );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
ICOM_VTBL(This) = &iqualitycontrol;
|
||||
This->punkControl = punkControl;
|
||||
This->pPin = pPin;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
void CQualityControlPassThruImpl_UninitIQualityControl(
|
||||
CQualityControlPassThruImpl* This )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ DEFAULT_DEBUG_CHANNEL(quartz);
|
||||
#include "quartz_private.h"
|
||||
#include "fgraph.h"
|
||||
|
||||
#define EVENTQUEUE_BLOCKSIZE 16
|
||||
#define EVENTQUEUE_BLOCKSIZE 2
|
||||
#define EVENTQUEUE_MAX 1024
|
||||
|
||||
struct FilterGraph_MEDIAEVENT
|
||||
@ -36,6 +36,106 @@ struct FilterGraph_MEDIAEVENT
|
||||
};
|
||||
|
||||
|
||||
static HRESULT FGEVENT_KeepEvent(
|
||||
BOOL bKeep,
|
||||
long lEventCode, LONG_PTR lParam1, LONG_PTR lParam2 )
|
||||
{
|
||||
switch ( lEventCode )
|
||||
{
|
||||
/*case EC_COMPLETE:*/
|
||||
case EC_USERABORT:
|
||||
break;
|
||||
case EC_ERRORABORT:
|
||||
break;
|
||||
case EC_TIME:
|
||||
break;
|
||||
/*case EC_REPAINT:*/
|
||||
case EC_STREAM_ERROR_STOPPED:
|
||||
break;
|
||||
case EC_STREAM_ERROR_STILLPLAYING:
|
||||
break;
|
||||
case EC_ERROR_STILLPLAYING:
|
||||
break;
|
||||
case EC_PALETTE_CHANGED:
|
||||
break;
|
||||
case EC_VIDEO_SIZE_CHANGED:
|
||||
break;
|
||||
case EC_QUALITY_CHANGE:
|
||||
break;
|
||||
/*case EC_SHUTTING_DOWN:*/
|
||||
case EC_CLOCK_CHANGED:
|
||||
break;
|
||||
case EC_PAUSED:
|
||||
break;
|
||||
|
||||
case EC_OPENING_FILE:
|
||||
break;
|
||||
case EC_BUFFERING_DATA:
|
||||
break;
|
||||
case EC_FULLSCREEN_LOST:
|
||||
if ( bKeep )
|
||||
{
|
||||
if ( ((IBaseFilter*)lParam2) != NULL )
|
||||
IBaseFilter_AddRef( (IBaseFilter*)lParam2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ((IBaseFilter*)lParam2) != NULL )
|
||||
IBaseFilter_Release( (IBaseFilter*)lParam2 );
|
||||
}
|
||||
break;
|
||||
/*case EC_ACTIVATE:*/
|
||||
/*case EC_NEED_RESTART:*/
|
||||
/*case EC_WINDOW_DESTROYED:*/
|
||||
/*case EC_DISPLAY_CHANGED:*/
|
||||
/*case EC_STARVATION:*/
|
||||
/*case EC_OLE_EVENT:*/
|
||||
/*case EC_NOTIFY_WINDOW:*/
|
||||
/*case EC_STREAM_CONTROL_STOPPED:*/
|
||||
/*case EC_STREAM_CONTROL_STARTED:*/
|
||||
/*case EC_END_OF_SEGMENT:*/
|
||||
/*case EC_SEGMENT_STARTED:*/
|
||||
case EC_LENGTH_CHANGED:
|
||||
break;
|
||||
case EC_DEVICE_LOST:
|
||||
if ( bKeep )
|
||||
{
|
||||
if ( ((IUnknown*)lParam1) != NULL )
|
||||
IUnknown_AddRef( (IUnknown*)lParam1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ((IUnknown*)lParam1) != NULL )
|
||||
IUnknown_Release( (IUnknown*)lParam1 );
|
||||
}
|
||||
break;
|
||||
|
||||
case EC_STEP_COMPLETE:
|
||||
break;
|
||||
case EC_SKIP_FRAMES:
|
||||
break;
|
||||
|
||||
/*case EC_TIMECODE_AVAILABLE:*/
|
||||
/*case EC_EXTDEVICE_MODE_CHANGE:*/
|
||||
|
||||
case EC_GRAPH_CHANGED:
|
||||
break;
|
||||
case EC_CLOCK_UNSET:
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( lEventCode < EC_USER )
|
||||
{
|
||||
FIXME( "unknown system event %08lx\n", lEventCode );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
TRACE( "user event %08lx\n", lEventCode );
|
||||
break;
|
||||
}
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* CLSID_FilterGraph::IMediaEvent[Ex]
|
||||
@ -129,7 +229,7 @@ static HRESULT WINAPI
|
||||
IMediaEventEx_fnGetEvent(IMediaEventEx* iface,long* plEventCode,LONG_PTR* plParam1,LONG_PTR* plParam2,long lTimeOut)
|
||||
{
|
||||
CFilterGraph_THIS(iface,mediaevent);
|
||||
ULONG cbQueued;
|
||||
ULONG cQueued;
|
||||
DWORD dw;
|
||||
DWORD dwStart;
|
||||
HRESULT hr;
|
||||
@ -154,11 +254,11 @@ IMediaEventEx_fnGetEvent(IMediaEventEx* iface,long* plEventCode,LONG_PTR* plPara
|
||||
hr = S_FALSE;
|
||||
if ( This->m_cbMediaEventsMax > 0 )
|
||||
{
|
||||
cbQueued =
|
||||
cQueued =
|
||||
(This->m_cbMediaEventsMax +
|
||||
This->m_cbMediaEventsPut - This->m_cbMediaEventsGet) %
|
||||
This->m_cbMediaEventsMax;
|
||||
if ( cbQueued > 0 )
|
||||
if ( cQueued > 0 )
|
||||
{
|
||||
pEvent = &This->m_pMediaEvents[This->m_cbMediaEventsGet];
|
||||
*plEventCode = pEvent->lEventCode;
|
||||
@ -168,6 +268,8 @@ IMediaEventEx_fnGetEvent(IMediaEventEx* iface,long* plEventCode,LONG_PTR* plPara
|
||||
This->m_cbMediaEventsMax;
|
||||
|
||||
hr = NOERROR;
|
||||
if ( This->m_cbMediaEventsPut == This->m_cbMediaEventsGet )
|
||||
ResetEvent( This->m_hMediaEvent );
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection( &This->m_csMediaEvents );
|
||||
@ -259,9 +361,9 @@ IMediaEventEx_fnFreeEventParams(IMediaEventEx* iface,long lEventCode,LONG_PTR lP
|
||||
{
|
||||
CFilterGraph_THIS(iface,mediaevent);
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->(%08lx,%08x,%08x)\n",This,lEventCode,lParam1,lParam2);
|
||||
|
||||
return E_NOTIMPL;
|
||||
return FGEVENT_KeepEvent( FALSE, lEventCode, lParam1, lParam2 );
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -269,9 +371,15 @@ IMediaEventEx_fnSetNotifyWindow(IMediaEventEx* iface,OAHWND hwnd,long message,LO
|
||||
{
|
||||
CFilterGraph_THIS(iface,mediaevent);
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->(%08x,%08lx,%08x)\n",This,hwnd,message,lParam);
|
||||
|
||||
return E_NOTIMPL;
|
||||
EnterCriticalSection( &This->m_csMediaEvents );
|
||||
This->m_hwndEventNotify = (HWND)hwnd;
|
||||
This->m_lEventNotifyMsg = message;
|
||||
This->m_lEventNotifyParam = lParam;
|
||||
LeaveCriticalSection( &This->m_csMediaEvents );
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -279,9 +387,16 @@ IMediaEventEx_fnSetNotifyFlags(IMediaEventEx* iface,long lNotifyFlags)
|
||||
{
|
||||
CFilterGraph_THIS(iface,mediaevent);
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->(%ld)\n",This,lNotifyFlags);
|
||||
|
||||
return E_NOTIMPL;
|
||||
if ( lNotifyFlags != 0 && lNotifyFlags != 1 )
|
||||
return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection( &This->m_csMediaEvents );
|
||||
This->m_lEventNotifyFlags = lNotifyFlags;
|
||||
LeaveCriticalSection( &This->m_csMediaEvents );
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -289,9 +404,16 @@ IMediaEventEx_fnGetNotifyFlags(IMediaEventEx* iface,long* plNotifyFlags)
|
||||
{
|
||||
CFilterGraph_THIS(iface,mediaevent);
|
||||
|
||||
FIXME("(%p)->() stub!\n",This);
|
||||
TRACE("(%p)->(%p)\n",This,plNotifyFlags);
|
||||
|
||||
return E_NOTIMPL;
|
||||
if ( plNotifyFlags == NULL )
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection( &This->m_csMediaEvents );
|
||||
*plNotifyFlags = This->m_lEventNotifyFlags;
|
||||
LeaveCriticalSection( &This->m_csMediaEvents );
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
|
||||
@ -336,6 +458,10 @@ HRESULT CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg )
|
||||
pfg->m_cbMediaEventsPut = 0;
|
||||
pfg->m_cbMediaEventsGet = 0;
|
||||
pfg->m_cbMediaEventsMax = 0;
|
||||
pfg->m_hwndEventNotify = (HWND)NULL;
|
||||
pfg->m_lEventNotifyMsg = 0;
|
||||
pfg->m_lEventNotifyParam = 0;
|
||||
pfg->m_lEventNotifyFlags = 0;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
@ -411,10 +537,98 @@ static HRESULT WINAPI
|
||||
IMediaEventSink_fnNotify(IMediaEventSink* iface,long lEventCode,LONG_PTR lParam1,LONG_PTR lParam2)
|
||||
{
|
||||
CFilterGraph_THIS(iface,mediaeventsink);
|
||||
HRESULT hr = NOERROR;
|
||||
ULONG cQueued;
|
||||
ULONG cTemp;
|
||||
FilterGraph_MEDIAEVENT* pEvent;
|
||||
|
||||
FIXME("(%p)->(%ld,%08x,%08x) stub!\n",This,lEventCode,lParam1,lParam2);
|
||||
TRACE("(%p)->(%08lx,%08x,%08x) stub!\n",This,lEventCode,lParam1,lParam2);
|
||||
|
||||
return E_NOTIMPL;
|
||||
EnterCriticalSection( &This->m_csMediaEvents );
|
||||
|
||||
/* allocate a new entry. */
|
||||
if ( This->m_cbMediaEventsMax == 0 )
|
||||
cQueued = 0;
|
||||
else
|
||||
cQueued =
|
||||
(This->m_cbMediaEventsMax +
|
||||
This->m_cbMediaEventsPut - This->m_cbMediaEventsGet) %
|
||||
This->m_cbMediaEventsMax;
|
||||
|
||||
if ( (cQueued + 1) >= This->m_cbMediaEventsMax )
|
||||
{
|
||||
if ( This->m_cbMediaEventsMax >= EVENTQUEUE_MAX )
|
||||
{
|
||||
hr = E_FAIL;
|
||||
goto end;
|
||||
}
|
||||
pEvent = (FilterGraph_MEDIAEVENT*)
|
||||
QUARTZ_AllocMem( sizeof(FilterGraph_MEDIAEVENT) *
|
||||
(This->m_cbMediaEventsMax+EVENTQUEUE_BLOCKSIZE) );
|
||||
if ( pEvent == NULL )
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto end;
|
||||
}
|
||||
if ( cQueued > 0 )
|
||||
{
|
||||
if ( (This->m_cbMediaEventsGet + cQueued) >=
|
||||
This->m_cbMediaEventsMax )
|
||||
{
|
||||
cTemp = This->m_cbMediaEventsMax - This->m_cbMediaEventsGet;
|
||||
memcpy(
|
||||
pEvent,
|
||||
&This->m_pMediaEvents[This->m_cbMediaEventsGet],
|
||||
sizeof(FilterGraph_MEDIAEVENT) * cTemp );
|
||||
memcpy(
|
||||
pEvent + cTemp,
|
||||
&This->m_pMediaEvents[0],
|
||||
sizeof(FilterGraph_MEDIAEVENT) * (cQueued - cTemp) );
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(
|
||||
pEvent,
|
||||
&This->m_pMediaEvents[This->m_cbMediaEventsGet],
|
||||
sizeof(FilterGraph_MEDIAEVENT) * cQueued );
|
||||
}
|
||||
QUARTZ_FreeMem( This->m_pMediaEvents );
|
||||
}
|
||||
This->m_pMediaEvents = pEvent;
|
||||
This->m_cbMediaEventsMax += EVENTQUEUE_BLOCKSIZE;
|
||||
This->m_cbMediaEventsPut = cQueued;
|
||||
This->m_cbMediaEventsGet = 0;
|
||||
}
|
||||
|
||||
/* duplicate params if necessary. */
|
||||
hr = FGEVENT_KeepEvent( TRUE, lEventCode, lParam1, lParam2 );
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
|
||||
/* add to the queue. */
|
||||
pEvent = &This->m_pMediaEvents[This->m_cbMediaEventsPut];
|
||||
pEvent->lEventCode = lEventCode;
|
||||
pEvent->lParam1 = lParam1;
|
||||
pEvent->lParam2 = lParam2;
|
||||
This->m_cbMediaEventsPut =
|
||||
(This->m_cbMediaEventsPut + 1) % This->m_cbMediaEventsMax;
|
||||
|
||||
SetEvent( This->m_hMediaEvent );
|
||||
if ( This->m_hwndEventNotify != (HWND)NULL &&
|
||||
This->m_lEventNotifyFlags == 0 )
|
||||
{
|
||||
PostMessageA(
|
||||
This->m_hwndEventNotify,
|
||||
This->m_lEventNotifyMsg,
|
||||
(WPARAM)0,
|
||||
(LPARAM)This->m_lEventNotifyParam );
|
||||
}
|
||||
|
||||
hr = NOERROR;
|
||||
end:
|
||||
LeaveCriticalSection( &This->m_csMediaEvents );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,6 +140,10 @@ typedef struct CFilterGraph
|
||||
ULONG m_cbMediaEventsPut;
|
||||
ULONG m_cbMediaEventsGet;
|
||||
ULONG m_cbMediaEventsMax;
|
||||
HWND m_hwndEventNotify;
|
||||
long m_lEventNotifyMsg;
|
||||
LONG_PTR m_lEventNotifyParam;
|
||||
long m_lEventNotifyFlags;
|
||||
/* IMediaEventSink fields. */
|
||||
/* IMediaPosition fields. */
|
||||
/* IMediaSeeking fields. */
|
||||
|
@ -80,6 +80,20 @@ static HRESULT CFilterGraph_DisconnectAllPins( IBaseFilter* pFilter )
|
||||
}
|
||||
|
||||
|
||||
static HRESULT CFilterGraph_GraphChanged( CFilterGraph* This )
|
||||
{
|
||||
/* IDistributorNotify_NotifyGraphChange() */
|
||||
|
||||
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
|
||||
EC_GRAPH_CHANGED, 0, 0);
|
||||
EnterCriticalSection( &This->m_csGraphVersion );
|
||||
This->m_lGraphVersion ++;
|
||||
LeaveCriticalSection( &This->m_csGraphVersion );
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static HRESULT WINAPI
|
||||
@ -220,12 +234,9 @@ name_ok:
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* IDistributorNotify_NotifyGraphChange() */
|
||||
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
|
||||
EC_GRAPH_CHANGED, 0, 0);
|
||||
EnterCriticalSection( &This->m_csGraphVersion );
|
||||
This->m_lGraphVersion ++;
|
||||
LeaveCriticalSection( &This->m_csGraphVersion );
|
||||
hr = CFilterGraph_GraphChanged(This);
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
|
||||
hr = hrSucceeded;
|
||||
end:
|
||||
@ -269,12 +280,9 @@ IFilterGraph2_fnRemoveFilter(IFilterGraph2* iface,IBaseFilter* pFilter)
|
||||
This->m_pFilterList, (IUnknown*)pFilter );
|
||||
}
|
||||
|
||||
/* IDistributorNotify_NotifyGraphChange() */
|
||||
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
|
||||
EC_GRAPH_CHANGED, 0, 0);
|
||||
EnterCriticalSection( &This->m_csGraphVersion );
|
||||
This->m_lGraphVersion ++;
|
||||
LeaveCriticalSection( &This->m_csGraphVersion );
|
||||
hr = CFilterGraph_GraphChanged(This);
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
|
||||
end:;
|
||||
QUARTZ_CompList_Unlock( This->m_pFilterList );
|
||||
@ -403,12 +411,9 @@ IFilterGraph2_fnConnectDirect(IFilterGraph2* iface,IPin* pOut,IPin* pIn,const AM
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* IDistributorNotify_NotifyGraphChange() */
|
||||
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
|
||||
EC_GRAPH_CHANGED, 0, 0);
|
||||
EnterCriticalSection( &This->m_csGraphVersion );
|
||||
This->m_lGraphVersion ++;
|
||||
LeaveCriticalSection( &This->m_csGraphVersion );
|
||||
hr = CFilterGraph_GraphChanged(This);
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
|
||||
end:
|
||||
QUARTZ_CompList_Unlock( This->m_pFilterList );
|
||||
@ -454,14 +459,14 @@ IFilterGraph2_fnDisconnect(IFilterGraph2* iface,IPin* pPin)
|
||||
IPin_Release(pConnTo);
|
||||
}
|
||||
hr = IPin_Disconnect(pPin);
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
|
||||
/* IDistributorNotify_NotifyGraphChange() */
|
||||
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
|
||||
EC_GRAPH_CHANGED, 0, 0);
|
||||
EnterCriticalSection( &This->m_csGraphVersion );
|
||||
This->m_lGraphVersion ++;
|
||||
LeaveCriticalSection( &This->m_csGraphVersion );
|
||||
hr = CFilterGraph_GraphChanged(This);
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
|
||||
end:
|
||||
QUARTZ_CompList_Unlock( This->m_pFilterList );
|
||||
|
||||
return hr;
|
||||
@ -657,17 +662,13 @@ static HRESULT WINAPI
|
||||
IFilterGraph2_fnReconnectEx(IFilterGraph2* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
|
||||
{
|
||||
CFilterGraph_THIS(iface,fgraph);
|
||||
HRESULT hr;
|
||||
|
||||
FIXME( "(%p)->(%p,%p) stub!\n",This,pPin,pmt );
|
||||
|
||||
/* reconnect asynchronously. */
|
||||
|
||||
/* IDistributorNotify_NotifyGraphChange() */
|
||||
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
|
||||
EC_GRAPH_CHANGED, 0, 0);
|
||||
EnterCriticalSection( &This->m_csGraphVersion );
|
||||
This->m_lGraphVersion ++;
|
||||
LeaveCriticalSection( &This->m_csGraphVersion );
|
||||
hr = CFilterGraph_GraphChanged(This);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
@ -348,12 +348,8 @@ IMediaFilter_fnSetSyncSource(IMediaFilter* iface,IReferenceClock* pobjClock)
|
||||
|
||||
QUARTZ_CompList_Unlock( This->m_pFilterList );
|
||||
|
||||
if ( This->m_pClock != NULL )
|
||||
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
|
||||
EC_CLOCK_CHANGED, 0, 0);
|
||||
else
|
||||
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
|
||||
EC_CLOCK_UNSET, 0, 0);
|
||||
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
|
||||
EC_CLOCK_CHANGED, 0, 0);
|
||||
|
||||
LeaveCriticalSection( &This->m_csClock );
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "mmsystem.h"
|
||||
#include "ole2.h"
|
||||
#include "wine/obj_oleaut.h"
|
||||
#include "strmif.h"
|
||||
@ -30,6 +31,7 @@ DEFAULT_DEBUG_CHANNEL(quartz);
|
||||
#include "fmap.h"
|
||||
#include "fmap2.h"
|
||||
#include "seekpass.h"
|
||||
#include "audren.h"
|
||||
|
||||
|
||||
typedef struct QUARTZ_CLASSENTRY
|
||||
@ -74,6 +76,7 @@ static const QUARTZ_CLASSENTRY QUARTZ_ClassList[] =
|
||||
{ &CLSID_FilterMapper, &QUARTZ_CreateFilterMapper },
|
||||
{ &CLSID_FilterMapper2, &QUARTZ_CreateFilterMapper2 },
|
||||
{ &CLSID_SeekingPassThru, &QUARTZ_CreateSeekingPassThru },
|
||||
{ &CLSID_AudioRender, &QUARTZ_CreateAudioRenderer },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
@ -292,6 +295,8 @@ BOOL WINAPI QUARTZ_DllMain(
|
||||
DWORD fdwReason,
|
||||
LPVOID lpvReserved )
|
||||
{
|
||||
TRACE("(%08x,%08lx,%p)\n",hInstDLL,fdwReason,lpvReserved);
|
||||
|
||||
switch ( fdwReason )
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
|
@ -287,6 +287,10 @@ IMemAllocator_fnDecommit(IMemAllocator* iface)
|
||||
|
||||
if ( !bBlock )
|
||||
{
|
||||
QUARTZ_FreeMem(This->ppSamples);
|
||||
This->ppSamples = NULL;
|
||||
QUARTZ_FreeMem(This->pData);
|
||||
This->pData = NULL;
|
||||
hr = NOERROR;
|
||||
break;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ init QUARTZ_DllMain
|
||||
|
||||
import oleaut32.dll
|
||||
import ole32.dll
|
||||
#import winmm.dll
|
||||
import winmm.dll
|
||||
import user32.dll
|
||||
#import gdi32.dll
|
||||
import advapi32.dll
|
||||
|
@ -491,6 +491,8 @@ HRESULT QUARTZ_CreateMemMediaSample(
|
||||
void QUARTZ_DestroyMemMediaSample(
|
||||
CMemMediaSample* pSample )
|
||||
{
|
||||
TRACE("(%p)\n",pSample);
|
||||
|
||||
QUARTZ_FreeObj( pSample );
|
||||
}
|
||||
|
||||
|
@ -1331,7 +1331,7 @@ ICOM_DEFINE(IMediaSample,IUnknown)
|
||||
#define IMediaSample_SetSyncPoint(p,a1) ICOM_CALL1(SetSyncPoint,p,a1)
|
||||
#define IMediaSample_IsPreroll(p) ICOM_CALL (IsPreroll,p)
|
||||
#define IMediaSample_SetPreroll(p,a1) ICOM_CALL1(SetPreroll,p,a1)
|
||||
#define IMediaSample_GetActualDataLength(p,a1) ICOM_CALL1(GetActualDataLength,p,a1)
|
||||
#define IMediaSample_GetActualDataLength(p) ICOM_CALL (GetActualDataLength,p)
|
||||
#define IMediaSample_SetActualDataLength(p,a1) ICOM_CALL1(SetActualDataLength,p,a1)
|
||||
#define IMediaSample_GetMediaType(p,a1) ICOM_CALL1(GetMediaType,p,a1)
|
||||
#define IMediaSample_SetMediaType(p,a1) ICOM_CALL1(SetMediaType,p,a1)
|
||||
|
@ -318,6 +318,16 @@
|
||||
"FriendlyName"="Audio Renderers"
|
||||
|
||||
|
||||
# CLSID_AudioRender
|
||||
|
||||
[HKEY_CLASSES_ROOT\CLSID\{e30629d1-27e5-11ce-875d-00608cb78066}\InprocServer32]
|
||||
@="quartz.dll"
|
||||
"ThreadingModel"="Both"
|
||||
|
||||
[HKEY_CLASSES_ROOT\CLSID\{E0F158E1-CB04-11D0-BD4E-00A0C911CE86}\Instance\{e30629d1-27e5-11ce-875d-00608cb78066}]
|
||||
"CLSID"="{e30629d1-27e5-11ce-875d-00608cb78066}"
|
||||
"FriendlyName"="Waveout audio renderer"
|
||||
|
||||
|
||||
#
|
||||
# Entries for Mozilla ActiveX control support
|
||||
|
Loading…
Reference in New Issue
Block a user