Commit a5585624 authored by Hidenori Takeshima's avatar Hidenori Takeshima Committed by Alexandre Julliard

Fixed some bugs.

Fixed audio renderer. Implemented seeking. Added some stubs.
parent 39bcf9d6
......@@ -20,10 +20,13 @@
#include <math.h>
#include "windef.h"
#include "wine/obj_base.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h"
/***********************************************************************
* AmpFactorToDB (QUARTZ.@)
*
......@@ -35,7 +38,7 @@ LONG WINAPI QUARTZ_AmpFactorToDB( LONG amp )
{
LONG dB;
FIXME( "(%08ld): undocumented API.\n", amp );
TRACE( "(%ld)\n", amp );
if ( amp <= 0 || amp > 65536 )
return 0;
......@@ -57,7 +60,7 @@ LONG WINAPI QUARTZ_DBToAmpFactor( LONG dB )
{
LONG amp;
FIXME( "(%08ld): undocumented API.\n", dB );
TRACE( "(%ld)\n", dB );
if ( dB >= 0 )
return 65535;
......
......@@ -3,7 +3,6 @@
*
* FIXME
* - implement IReferenceClock.
* - implement seeking.
*
* Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
*
......@@ -209,9 +208,6 @@ err:
return hr;
}
#if 0
/* FIXME: Not used for now */
static HRESULT CAudioRendererImpl_waveOutPause( CAudioRendererImpl* This )
{
if ( !This->m_fWaveOutInit )
......@@ -229,7 +225,6 @@ static HRESULT CAudioRendererImpl_waveOutRun( CAudioRendererImpl* This )
return QUARTZ_HRESULT_From_MMRESULT( waveOutRestart(
This->m_hWaveOut ) );
}
#endif
static
WAVEHDR* CAudioRendererImpl_waveOutGetBuffer(
......@@ -341,6 +336,8 @@ HRESULT CAudioRendererImpl_waveOutGetVolume(
return NOERROR;
}
#endif
static
HRESULT CAudioRendererImpl_waveOutSetVolume(
CAudioRendererImpl* This,
......@@ -358,7 +355,34 @@ HRESULT CAudioRendererImpl_waveOutSetVolume(
This->m_hWaveOut, dwVol );
return QUARTZ_HRESULT_From_MMRESULT( mr );
}
#endif
static HRESULT CAudioRendererImpl_UpdateVolume( CAudioRendererImpl* This )
{
HRESULT hr;
long leftlevel;
long rightlevel;
if ( This->m_lAudioBalance >= 0 )
{
leftlevel = This->m_lAudioVolume - This->m_lAudioBalance;
rightlevel = This->m_lAudioVolume;
}
else
{
leftlevel = This->m_lAudioVolume;
rightlevel = This->m_lAudioVolume + This->m_lAudioBalance;
}
leftlevel = QUARTZ_DBToAmpFactor( leftlevel );
rightlevel = QUARTZ_DBToAmpFactor( rightlevel );
hr = CAudioRendererImpl_waveOutSetVolume(
This, (DWORD)leftlevel, (DWORD)rightlevel );
if ( hr == E_UNEXPECTED )
hr = S_OK;
return hr;
}
/***************************************************************************
*
......@@ -370,7 +394,7 @@ HRESULT CAudioRendererImpl_waveOutSetVolume(
static HRESULT CAudioRendererImpl_OnActive( CBaseFilterImpl* pImpl )
{
CAudioRendererImpl_THIS(pImpl,basefilter);
/* HRESULT hr; */
HRESULT hr;
FIXME( "(%p)\n", This );
......@@ -379,11 +403,9 @@ static HRESULT CAudioRendererImpl_OnActive( CBaseFilterImpl* pImpl )
This->m_fInFlush = FALSE;
/* FIXME - don't work correctly.
hr = CAudioRendererImpl_waveOutRun(This);
if ( FAILED(hr) )
return hr;
*/
return NOERROR;
}
......@@ -409,11 +431,9 @@ static HRESULT CAudioRendererImpl_OnInactive( CBaseFilterImpl* pImpl )
if ( FAILED(hr) )
return hr;
/* FIXME - may cause deadlock.
hr = CAudioRendererImpl_waveOutPause(This);
if ( FAILED(hr) )
return hr;
*/
return NOERROR;
}
......@@ -424,6 +444,8 @@ static HRESULT CAudioRendererImpl_OnStop( CBaseFilterImpl* pImpl )
FIXME( "(%p)\n", This );
This->m_fInFlush = TRUE;
CAudioRendererImpl_waveOutUninit(This);
This->m_fInFlush = FALSE;
......@@ -511,12 +533,10 @@ static HRESULT CAudioRendererPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample*
DWORD dwDataLength;
DWORD dwWritten;
FIXME( "(%p,%p)\n",This,pSample );
TRACE( "(%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;
......@@ -529,6 +549,9 @@ static HRESULT CAudioRendererPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample*
{
TRACE("trying to write %lu bytes\n",dwDataLength);
if ( This->pRender->m_fInFlush )
return S_FALSE;
ResetEvent( This->pRender->m_hEventRender );
hr = CAudioRendererImpl_waveOutWriteData(
This->pRender,pData,dwDataLength,&dwWritten);
......@@ -695,6 +718,8 @@ HRESULT QUARTZ_CreateAudioRenderer(IUnknown* punkOuter,void** ppobj)
This->pSeekPass = NULL;
This->pPin = NULL;
This->m_fInFlush = FALSE;
This->m_lAudioVolume = 0;
This->m_lAudioBalance = 0;
This->m_fWaveOutInit = FALSE;
This->m_hEventRender = (HANDLE)NULL;
......@@ -919,10 +944,19 @@ static HRESULT WINAPI
IBasicAudio_fnput_Volume(IBasicAudio* iface,long lVol)
{
CAudioRendererImpl_THIS(iface,basaud);
HRESULT hr;
FIXME("(%p)->()\n",This);
FIXME("(%p)->(%ld)\n",This,lVol);
return E_NOTIMPL;
if ( lVol > 0 || lVol < -10000 )
return E_INVALIDARG;
EnterCriticalSection( &This->basefilter.csFilter );
This->m_lAudioVolume = lVol;
hr = CAudioRendererImpl_UpdateVolume( This );
LeaveCriticalSection( &This->basefilter.csFilter );
return hr;
}
static HRESULT WINAPI
......@@ -930,19 +964,35 @@ IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol)
{
CAudioRendererImpl_THIS(iface,basaud);
FIXME("(%p)->()\n",This);
FIXME("(%p)->(%p)\n",This,plVol);
return E_NOTIMPL;
if ( plVol == NULL )
return E_POINTER;
EnterCriticalSection( &This->basefilter.csFilter );
*plVol = This->m_lAudioVolume;
LeaveCriticalSection( &This->basefilter.csFilter );
return S_OK;
}
static HRESULT WINAPI
IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance)
{
CAudioRendererImpl_THIS(iface,basaud);
HRESULT hr;
FIXME("(%p)->()\n",This);
FIXME("(%p)->(%ld)\n",This,lBalance);
return E_NOTIMPL;
if ( lBalance > 0 || lBalance < -10000 )
return E_INVALIDARG;
EnterCriticalSection( &This->basefilter.csFilter );
This->m_lAudioBalance = lBalance;
hr = CAudioRendererImpl_UpdateVolume( This );
LeaveCriticalSection( &This->basefilter.csFilter );
return hr;
}
static HRESULT WINAPI
......@@ -950,9 +1000,16 @@ IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance)
{
CAudioRendererImpl_THIS(iface,basaud);
FIXME("(%p)->()\n",This);
FIXME("(%p)->(%p)\n",This,plBalance);
return E_NOTIMPL;
if ( plBalance == NULL )
return E_POINTER;
EnterCriticalSection( &This->basefilter.csFilter );
*plBalance = This->m_lAudioBalance;
LeaveCriticalSection( &This->basefilter.csFilter );
return S_OK;
}
......
......@@ -53,6 +53,8 @@ struct CAudioRendererImpl
BOOL m_fInFlush;
/* for waveOut */
long m_lAudioVolume;
long m_lAudioBalance;
BOOL m_fWaveOutInit;
HANDLE m_hEventRender;
HWAVEOUT m_hWaveOut;
......
......@@ -440,6 +440,7 @@ static const TransformBaseHandlers transhandlers =
AVIDec_GetOutputTypes,
AVIDec_GetAllocProp,
AVIDec_BeginTransform,
NULL,
AVIDec_Transform,
AVIDec_EndTransform,
};
......
......@@ -570,7 +570,7 @@ static HRESULT CAVIParseImpl_GetAllocProp( CParserImpl* pImpl, ALLOCATOR_PROPERT
return NOERROR;
}
static HRESULT CAVIParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStreamIndex, LONGLONG* pllStart, LONG* plLength, REFERENCE_TIME* prtStart, REFERENCE_TIME* prtStop )
static HRESULT CAVIParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStreamIndex, LONGLONG* pllStart, LONG* plLength, REFERENCE_TIME* prtStart, REFERENCE_TIME* prtStop, DWORD* pdwSampleFlags )
{
CAVIParseImpl* This = (CAVIParseImpl*)pImpl->m_pUserData;
REFERENCE_TIME rtNext;
......@@ -579,10 +579,11 @@ static HRESULT CAVIParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStream
CAVIParseStream* pStream;
const WAVEFORMATEX* pwfx;
TRACE("(%p)\n",This);
if ( This == NULL )
return E_UNEXPECTED;
TRACE("(%p)\n",This);
*pdwSampleFlags = AM_SAMPLE_SPLICEPOINT;
nIndexNext = This->avih.dwStreams;
rtNext = ((REFERENCE_TIME)0x7fffffff<<32)|((REFERENCE_TIME)0xffffffff);
......@@ -607,6 +608,8 @@ static HRESULT CAVIParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStream
*plLength = (LONG)pStream->pIndexEntries[pStream->cIndexCur].dwChunkLength;
*prtStart = rtNext;
*prtStop = rtNext;
/* FIXME - is this frame keyframe?? */
*pdwSampleFlags = AM_SAMPLE_SPLICEPOINT;
switch ( pStream->strh.fccType )
{
......@@ -690,11 +693,9 @@ static const struct ParserHandlers CAVIParseImpl_Handlers =
NULL, /* pGetCurPos */
NULL, /* pSetCurPos */
NULL, /* pGetDuration */
NULL, /* pSetDuration */
NULL, /* pGetStopPos */
NULL, /* pSetStopPos */
NULL, /* pGetPreroll */
NULL, /* pSetPreroll */
};
HRESULT QUARTZ_CreateAVISplitter(IUnknown* punkOuter,void** ppobj)
......
......@@ -124,7 +124,9 @@ CPinBaseImpl_fnConnect(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
hr = IPin_QueryAccept(iface,pmt);
if ( FAILED(hr) )
goto err;
This->pPinConnectedTo = pPin;
hr = IPin_ReceiveConnection(pPin,iface,pmt);
This->pPinConnectedTo = NULL;
if ( FAILED(hr) )
goto err;
}
......@@ -136,7 +138,10 @@ CPinBaseImpl_fnConnect(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
hr = IPin_QueryAccept(iface,pmt);
if ( SUCCEEDED(hr) )
{
This->pPinConnectedTo = pPin;
hr = IPin_ReceiveConnection(pPin,iface,pmt);
This->pPinConnectedTo = NULL;
TRACE("ReceiveConnection - %08lx\n",hr);
if ( SUCCEEDED(hr) )
{
......
......@@ -81,9 +81,9 @@ ICaptureGraphBuilder_fnSetFiltergraph(ICaptureGraphBuilder* iface,IGraphBuilder*
{
CCaptureGraph_THIS(iface,capgraph1);
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
return ICaptureGraphBuilder2_SetFiltergraph(CCaptureGraph_ICaptureGraphBuilder2(This),pgb);
}
static HRESULT WINAPI
......@@ -91,9 +91,9 @@ ICaptureGraphBuilder_fnGetFiltergraph(ICaptureGraphBuilder* iface,IGraphBuilder*
{
CCaptureGraph_THIS(iface,capgraph1);
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
return ICaptureGraphBuilder2_GetFiltergraph(CCaptureGraph_ICaptureGraphBuilder2(This),ppgb);
}
static HRESULT WINAPI
......@@ -141,9 +141,9 @@ ICaptureGraphBuilder_fnAllocCapFile(ICaptureGraphBuilder* iface,LPCOLESTR pName,
{
CCaptureGraph_THIS(iface,capgraph1);
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
return ICaptureGraphBuilder2_AllocCapFile(CCaptureGraph_ICaptureGraphBuilder2(This),pName,llSize);
}
static HRESULT WINAPI
......@@ -151,9 +151,9 @@ ICaptureGraphBuilder_fnCopyCaptureFile(ICaptureGraphBuilder* iface,LPOLESTR pOrg
{
CCaptureGraph_THIS(iface,capgraph1);
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
return ICaptureGraphBuilder2_CopyCaptureFile(CCaptureGraph_ICaptureGraphBuilder2(This),pOrgName,pNewName,fAllowEscAbort,pCallback);
}
static ICOM_VTABLE(ICaptureGraphBuilder) icapgraph1 =
......
......@@ -46,6 +46,8 @@ typedef struct CCaptureGraph
#define CCaptureGraph_THIS(iface,member) CCaptureGraph* This = ((CCaptureGraph*)(((char*)iface)-offsetof(CCaptureGraph,member)))
#define CCaptureGraph_ICaptureGraphBuilder(th) ((ICaptureGraphBuilder*)&((th)->capgraph1))
#define CCaptureGraph_ICaptureGraphBuilder2(th) ((ICaptureGraphBuilder2*)&((th)->capgraph2))
HRESULT QUARTZ_CreateCaptureGraph(IUnknown* punkOuter,void** ppobj);
......
......@@ -435,6 +435,7 @@ static const TransformBaseHandlers transhandlers =
ColorConv_GetOutputTypes,
ColorConv_GetAllocProp,
ColorConv_BeginTransform,
NULL,
ColorConv_Transform,
ColorConv_EndTransform,
};
......
......@@ -39,23 +39,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz);
static HRESULT CFilterGraph_QIFilters(
CFilterGraph* This, REFIID riid, void** ppvobj )
{
QUARTZ_CompListItem* pItem;
HRESULT hr = E_NOINTERFACE;
DWORD n;
TRACE( "(%p,%p,%p)\n",This,riid,ppvobj);
QUARTZ_CompList_Lock( This->m_pFilterList );
pItem = QUARTZ_CompList_GetLast( This->m_pFilterList );
while ( pItem != NULL )
EnterCriticalSection ( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( IUnknown_QueryInterface( QUARTZ_CompList_GetItemPtr(pItem),riid,ppvobj) == S_OK )
if ( IUnknown_QueryInterface(This->m_pActiveFilters[n].pFilter,riid,ppvobj) == S_OK )
{
hr = S_OK;
break;
}
pItem = QUARTZ_CompList_GetPrev( This->m_pFilterList, pItem );
}
QUARTZ_CompList_Unlock( This->m_pFilterList );
LeaveCriticalSection ( &This->m_csFilters );
return hr;
}
......
......@@ -62,6 +62,7 @@ static QUARTZ_IFEntry IFEntries[] =
{ &IID_IBasicVideo2, offsetof(CFilterGraph,basvid)-offsetof(CFilterGraph,unk) },
{ &IID_IBasicAudio, offsetof(CFilterGraph,basaud)-offsetof(CFilterGraph,unk) },
{ &IID_IVideoWindow, offsetof(CFilterGraph,vidwin)-offsetof(CFilterGraph,unk) },
{ &IID_IAMStats, offsetof(CFilterGraph,amstats)-offsetof(CFilterGraph,unk) },
};
......@@ -89,6 +90,7 @@ static const struct FGInitEntry FGRAPH_Init[] =
FGENT(IBasicVideo2)
FGENT(IBasicAudio)
FGENT(IVideoWindow)
FGENT(IAMStats)
#undef FGENT
{ NULL, NULL },
......@@ -339,3 +341,176 @@ void CFilterGraph_UninitIDispatch( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
}
/***************************************************************************
*
* CFilterGraph::IAMStats
*
*/
static HRESULT WINAPI
IAMStats_fnQueryInterface(IAMStats* iface,REFIID riid,void** ppobj)
{
CFilterGraph_THIS(iface,amstats);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IAMStats_fnAddRef(IAMStats* iface)
{
CFilterGraph_THIS(iface,amstats);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IAMStats_fnRelease(IAMStats* iface)
{
CFilterGraph_THIS(iface,amstats);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
IAMStats_fnGetTypeInfoCount(IAMStats* iface,UINT* pcTypeInfo)
{
CFilterGraph_THIS(iface,amstats);
FIXME("(%p)->()\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IAMStats_fnGetTypeInfo(IAMStats* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
{
CFilterGraph_THIS(iface,amstats);
FIXME("(%p)->()\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IAMStats_fnGetIDsOfNames(IAMStats* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
{
CFilterGraph_THIS(iface,amstats);
FIXME("(%p)->()\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IAMStats_fnInvoke(IAMStats* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
CFilterGraph_THIS(iface,amstats);
FIXME("(%p)->()\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IAMStats_fnReset(IAMStats* iface)
{
CFilterGraph_THIS(iface,amstats);
FIXME("(%p) stub\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IAMStats_fnget_Count(IAMStats* iface,long* plCount)
{
CFilterGraph_THIS(iface,amstats);
FIXME("(%p,%p) stub\n",This,plCount);
if ( plCount == NULL )
return E_POINTER;
*plCount = 0;
return E_NOTIMPL;
}
static HRESULT WINAPI
IAMStats_fnGetValueByIndex(IAMStats* iface,long lIndex,BSTR* pbstrName,long* lCount,double* pdblLast,double* pdblAverage,double* pdblStdDev,double* pdblMin,double* pdblMax)
{
CFilterGraph_THIS(iface,amstats);
FIXME("(%p) stub\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IAMStats_fnGetValueByName(IAMStats* iface,BSTR bstrName,long* plIndex,long* plCount,double* pdblLast,double* pdblAverage,double* pdblStdDev,double* pdblMin,double* pdblMax)
{
CFilterGraph_THIS(iface,amstats);
FIXME("(%p) stub\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IAMStats_fnGetIndex(IAMStats* iface,BSTR bstrName,long lCreate,long* plIndex)
{
CFilterGraph_THIS(iface,amstats);
FIXME("(%p) stub\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IAMStats_fnAddValue(IAMStats* iface,long lIndex,double dValue)
{
CFilterGraph_THIS(iface,amstats);
FIXME("(%p) stub\n",This);
return E_NOTIMPL;
}
static ICOM_VTABLE(IAMStats) iamstats =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IAMStats_fnQueryInterface,
IAMStats_fnAddRef,
IAMStats_fnRelease,
/* IDispatch fields */
IAMStats_fnGetTypeInfoCount,
IAMStats_fnGetTypeInfo,
IAMStats_fnGetIDsOfNames,
IAMStats_fnInvoke,
/* IAMStats fields */
IAMStats_fnReset,
IAMStats_fnget_Count,
IAMStats_fnGetValueByIndex,
IAMStats_fnGetValueByName,
IAMStats_fnGetIndex,
IAMStats_fnAddValue,
};
HRESULT CFilterGraph_InitIAMStats( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
ICOM_VTBL(&pfg->amstats) = &iamstats;
return NOERROR;
}
void CFilterGraph_UninitIAMStats( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
}
......@@ -39,6 +39,7 @@
+ IDispatch - IBasicVideo[2] (pass to a renderer)
+ IDispatch - IBasicAudio (pass to a renderer)
+ IDispatch - IVideoWindow (pass to a renderer)
+ IDispatch - IAMStats
(following interfaces are not implemented)
+ IMarshal
+ IFilterMapper2 - IFilterMapper3
......@@ -119,6 +120,21 @@ typedef struct FG_IVideoWindowImpl
ICOM_VFIELD(IVideoWindow);
} FG_IVideoWindowImpl;
typedef struct FG_IAMStatsImpl
{
ICOM_VFIELD(IAMStats);
} FG_IAMStatsImpl;
typedef struct FG_FilterData
{
IBaseFilter* pFilter;
IMediaPosition* pPosition;
IMediaSeeking* pSeeking;
WCHAR* pwszName;
DWORD cbName;
} FG_FilterData;
typedef struct FilterGraph_MEDIAEVENT FilterGraph_MEDIAEVENT;
typedef struct CFilterGraph
......@@ -138,10 +154,13 @@ typedef struct CFilterGraph
FG_IBasicVideoImpl basvid;
FG_IBasicAudioImpl basaud;
FG_IVideoWindowImpl vidwin;
FG_IAMStatsImpl amstats;
/* IDispatch fields. */
/* IFilterGraph2 fields. */
QUARTZ_CompList* m_pFilterList;
CRITICAL_SECTION m_csFilters;
DWORD m_cActiveFilters;
FG_FilterData* m_pActiveFilters;
/* IGraphVersion fields. */
LONG m_lGraphVersion;
/* IMediaControl fields. */
......@@ -167,6 +186,7 @@ typedef struct CFilterGraph
/* IBasicVideo2 fields. */
/* IBasicAudio fields. */
/* IVideoWindow fields. */
/* IAMStats fields. */
} CFilterGraph;
#define CFilterGraph_THIS(iface,member) CFilterGraph* This = ((CFilterGraph*)(((char*)iface)-offsetof(CFilterGraph,member)))
......@@ -208,6 +228,8 @@ HRESULT CFilterGraph_InitIBasicAudio( CFilterGraph* pfg );
void CFilterGraph_UninitIBasicAudio( CFilterGraph* pfg );
HRESULT CFilterGraph_InitIVideoWindow( CFilterGraph* pfg );
void CFilterGraph_UninitIVideoWindow( CFilterGraph* pfg );
HRESULT CFilterGraph_InitIAMStats( CFilterGraph* pfg );
void CFilterGraph_UninitIAMStats( CFilterGraph* pfg );
#endif /* WINE_DSHOW_FGRAPH_H */
......@@ -142,6 +142,9 @@ static HRESULT CFileWriterPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pS
LONG lLength;
ULONG cbWritten;
HRESULT hr;
REFERENCE_TIME rtStart;
REFERENCE_TIME rtEnd;
LARGE_INTEGER dlibMove;
TRACE( "(%p,%p)\n",This,pSample );
......@@ -163,7 +166,16 @@ static HRESULT CFileWriterPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pS
return S_OK;
}
hr = IStream_Write((IStream*)(&This->stream),pData,lLength,&cbWritten);
hr = IMediaSample_GetTime( pSample, &rtStart, &rtEnd );
if ( FAILED(hr) )
return hr;
dlibMove.QuadPart = rtStart;
hr = IStream_Seek(CFileWriterPinImpl_IStream(This),dlibMove,STREAM_SEEK_SET,NULL);
if ( FAILED(hr) )
return hr;
hr = IStream_Write(CFileWriterPinImpl_IStream(This),pData,lLength,&cbWritten);
return hr;
}
......
......@@ -73,6 +73,8 @@ struct CFileWriterPinImpl
#define CFileWriterImpl_THIS(iface,member) CFileWriterImpl* This = ((CFileWriterImpl*)(((char*)iface)-offsetof(CFileWriterImpl,member)))
#define CFileWriterPinImpl_THIS(iface,member) CFileWriterPinImpl* This = ((CFileWriterPinImpl*)(((char*)iface)-offsetof(CFileWriterPinImpl,member)))
#define CFileWriterPinImpl_IStream(th) ((IStream*)&((th)->stream))
HRESULT CFileWriterPinImpl_InitIStream( CFileWriterPinImpl* This );
HRESULT CFileWriterPinImpl_UninitIStream( CFileWriterPinImpl* This );
......
......@@ -379,6 +379,7 @@ BOOL QUARTZ_CheckPinType( BOOL bExactMatch, const REGFILTERPINS2* pPin, DWORD cT
}
}
}
TRACE("Check media type %d\n",(int)bMatch);
if ( !bMatch )
return FALSE;
}
......@@ -394,6 +395,7 @@ BOOL QUARTZ_CheckPinType( BOOL bExactMatch, const REGFILTERPINS2* pPin, DWORD cT
break;
}
}
TRACE("Check medium %d\n",(int)bMatch);
if ( !bMatch )
return FALSE;
}
......@@ -408,7 +410,10 @@ BOOL QUARTZ_CheckPinType( BOOL bExactMatch, const REGFILTERPINS2* pPin, DWORD cT
}
if ( bRender && (!(pPin->dwFlags & REG_PINFLAG_B_RENDERER)) )
{
TRACE("not a renderer\n");
return FALSE;
}
return TRUE;
}
......@@ -926,6 +931,14 @@ IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,
QUARTZ_FreeMem(pbFilterData);
pbFilterData = NULL;
}
if(TRACE_ON(quartz))
{
CLSID clsidTrace;
if (SUCCEEDED(QUARTZ_GetCLSIDFromMoniker(pFilter,&clsidTrace)))
{
TRACE("moniker clsid %s\n",debugstr_guid(&clsidTrace));
}
}
hr = QUARTZ_GetFilterDataFromMoniker(pFilter,&pbFilterData,&cbFilterData);
if ( hr != S_OK )
continue;
......@@ -938,7 +951,7 @@ IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,
prf2 = QUARTZ_RegFilterV2FromFilterData(pbFilterData,cbFilterData);
if ( prf2 == NULL )
continue;
TRACE("prf2 %p, Merit %lu\n",prf2,prf2->dwMerit);
TRACE("prf2 %p, Merit %08lx\n",prf2,prf2->dwMerit);
if ( prf2->dwMerit < dwMerit || prf2->dwVersion != 2 )
continue;
......@@ -956,7 +969,10 @@ IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,
break;
}
if ( !bMatch )
{
TRACE("no matching input pin\n");
continue;
}
}
/* check output pins. */
......@@ -973,7 +989,10 @@ IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,
break;
}
if ( !bMatch )
{
TRACE("no matching output pin\n");
continue;
}
}
/* matched - add pFilter to the list. */
......@@ -986,6 +1005,7 @@ IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,
goto err;
}
}
TRACE("matched\n");
hr = QUARTZ_CompList_AddComp(
pList, (IUnknown*)pFilter, NULL, 0 );
if ( FAILED(hr) )
......
......@@ -50,28 +50,22 @@ HRESULT CFilterGraph_PollGraphState(
FILTER_STATE* pState)
{
HRESULT hr;
QUARTZ_CompListItem* pItem;
IBaseFilter* pFilter;
DWORD n;
hr = S_OK;
*pState = State_Stopped;
EnterCriticalSection( &This->m_csGraphState );
QUARTZ_CompList_Lock( This->m_pFilterList );
EnterCriticalSection( &This->m_csFilters );
pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
while ( pItem != NULL )
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
hr = IBaseFilter_GetState( pFilter, (DWORD)0, pState );
hr = IBaseFilter_GetState( This->m_pActiveFilters[n].pFilter, (DWORD)0, pState );
if ( hr != S_OK )
break;
pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
}
QUARTZ_CompList_Unlock( This->m_pFilterList );
LeaveCriticalSection( &This->m_csFilters );
LeaveCriticalSection( &This->m_csGraphState );
TRACE( "returns %08lx, state %d\n",
......@@ -80,6 +74,118 @@ HRESULT CFilterGraph_PollGraphState(
return hr;
}
static
HRESULT CFilterGraph_StopGraph(
CFilterGraph* This )
{
HRESULT hr;
HRESULT hrFilter;
DWORD n;
hr = S_OK;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
hrFilter = IBaseFilter_Stop( This->m_pActiveFilters[n].pFilter );
if ( hrFilter != S_OK )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static
HRESULT CFilterGraph_PauseGraph(
CFilterGraph* This )
{
HRESULT hr;
HRESULT hrFilter;
DWORD n;
hr = S_OK;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
hrFilter = IBaseFilter_Pause( This->m_pActiveFilters[n].pFilter );
if ( hrFilter != S_OK )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static
HRESULT CFilterGraph_RunGraph(
CFilterGraph* This, REFERENCE_TIME rtStart )
{
HRESULT hr;
HRESULT hrFilter;
DWORD n;
hr = S_OK;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
hrFilter = IBaseFilter_Run( This->m_pActiveFilters[n].pFilter, rtStart );
if ( hrFilter != S_OK )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static
HRESULT CFilterGraph_SetSyncSourceGraph(
CFilterGraph* This, IReferenceClock* pClock )
{
HRESULT hr;
HRESULT hrFilter;
DWORD n;
hr = S_OK;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
hrFilter = IBaseFilter_SetSyncSource( This->m_pActiveFilters[n].pFilter, pClock );
if ( hrFilter == E_NOTIMPL )
hrFilter = S_OK;
if ( hrFilter != S_OK )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
/*****************************************************************************/
static HRESULT WINAPI
......@@ -129,9 +235,6 @@ IMediaFilter_fnStop(IMediaFilter* iface)
{
CFilterGraph_THIS(iface,mediafilter);
HRESULT hr;
HRESULT hrFilter;
QUARTZ_CompListItem* pItem;
IBaseFilter* pFilter;
TRACE("(%p)->()\n",This);
......@@ -143,24 +246,7 @@ IMediaFilter_fnStop(IMediaFilter* iface)
{
/* IDistributorNotify_Stop() */
QUARTZ_CompList_Lock( This->m_pFilterList );
pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
while ( pItem != NULL )
{
pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
hrFilter = IBaseFilter_Stop( pFilter );
if ( hrFilter != S_OK )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
}
QUARTZ_CompList_Unlock( This->m_pFilterList );
hr = CFilterGraph_StopGraph(This);
This->m_stateGraph = State_Stopped;
}
......@@ -175,9 +261,6 @@ IMediaFilter_fnPause(IMediaFilter* iface)
{
CFilterGraph_THIS(iface,mediafilter);
HRESULT hr;
HRESULT hrFilter;
QUARTZ_CompListItem* pItem;
IBaseFilter* pFilter;
TRACE("(%p)->()\n",This);
......@@ -189,26 +272,11 @@ IMediaFilter_fnPause(IMediaFilter* iface)
{
/* IDistributorNotify_Pause() */
QUARTZ_CompList_Lock( This->m_pFilterList );
pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
while ( pItem != NULL )
{
pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
hrFilter = IBaseFilter_Pause( pFilter );
if ( hrFilter != S_OK )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
}
QUARTZ_CompList_Unlock( This->m_pFilterList );
This->m_stateGraph = State_Paused;
hr = CFilterGraph_PauseGraph(This);
if ( SUCCEEDED(hr) )
This->m_stateGraph = State_Paused;
else
(void)CFilterGraph_StopGraph(This);
}
LeaveCriticalSection( &This->m_csGraphState );
......@@ -221,9 +289,6 @@ IMediaFilter_fnRun(IMediaFilter* iface,REFERENCE_TIME rtStart)
{
CFilterGraph_THIS(iface,mediafilter);
HRESULT hr;
HRESULT hrFilter;
QUARTZ_CompListItem* pItem;
IBaseFilter* pFilter;
IReferenceClock* pClock;
TRACE("(%p)->()\n",This);
......@@ -254,26 +319,12 @@ IMediaFilter_fnRun(IMediaFilter* iface,REFERENCE_TIME rtStart)
{
/* IDistributorNotify_Run() */
QUARTZ_CompList_Lock( This->m_pFilterList );
pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
hr = CFilterGraph_RunGraph(This,rtStart);
while ( pItem != NULL )
{
pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
hrFilter = IBaseFilter_Run( pFilter, rtStart );
if ( hrFilter != S_OK )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
}
QUARTZ_CompList_Unlock( This->m_pFilterList );
This->m_stateGraph = State_Running;
if ( SUCCEEDED(hr) )
This->m_stateGraph = State_Running;
else
(void)CFilterGraph_StopGraph(This);
}
end:
......@@ -327,43 +378,34 @@ static HRESULT WINAPI
IMediaFilter_fnSetSyncSource(IMediaFilter* iface,IReferenceClock* pobjClock)
{
CFilterGraph_THIS(iface,mediafilter);
QUARTZ_CompListItem* pItem;
IBaseFilter* pFilter;
HRESULT hr = NOERROR;
HRESULT hrCur;
TRACE("(%p)->(%p)\n",This,pobjClock);
/* IDistributorNotify_SetSyncSource() */
EnterCriticalSection( &This->m_csClock );
QUARTZ_CompList_Lock( This->m_pFilterList );
if ( This->m_pClock != NULL )
hr = CFilterGraph_SetSyncSourceGraph( This, pobjClock );
if ( SUCCEEDED(hr) )
{
IReferenceClock_Release(This->m_pClock);
This->m_pClock = NULL;
if ( This->m_pClock != NULL )
{
IReferenceClock_Release(This->m_pClock);
This->m_pClock = NULL;
}
This->m_pClock = pobjClock;
if ( pobjClock != NULL )
IReferenceClock_AddRef( pobjClock );
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
EC_CLOCK_CHANGED, 0, 0);
}
This->m_pClock = pobjClock;
if ( pobjClock != NULL )
IReferenceClock_AddRef( pobjClock );
pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
while ( pItem != NULL )
else
{
pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
hrCur = IBaseFilter_SetSyncSource(pFilter,pobjClock);
if ( FAILED(hrCur) )
hr = hrCur;
pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
(void)CFilterGraph_SetSyncSourceGraph( This, This->m_pClock );
}
QUARTZ_CompList_Unlock( This->m_pFilterList );
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
EC_CLOCK_CHANGED, 0, 0);
LeaveCriticalSection( &This->m_csClock );
TRACE( "hr = %08lx\n", hr );
......
......@@ -118,110 +118,385 @@ static HRESULT WINAPI
IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
{
CFilterGraph_THIS(iface,mediaposition);
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
HRESULT hr = E_NOTIMPL;
HRESULT hrFilter;
DWORD n;
TRACE("(%p)->(%p)\n",This,prefTime);
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( This->m_pActiveFilters[n].pPosition != NULL )
{
hrFilter = IMediaPosition_get_Duration( This->m_pActiveFilters[n].pPosition, prefTime );
if ( hr == E_NOTIMPL )
{
hr = hrFilter;
}
else
if ( hrFilter != E_NOTIMPL )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static HRESULT WINAPI
IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
{
CFilterGraph_THIS(iface,mediaposition);
HRESULT hr = E_NOTIMPL;
HRESULT hrFilter;
DWORD n;
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( This->m_pActiveFilters[n].pPosition != NULL )
{
hrFilter = IMediaPosition_put_CurrentPosition( This->m_pActiveFilters[n].pPosition, refTime );
if ( hr == E_NOTIMPL )
{
hr = hrFilter;
}
else
if ( hrFilter != E_NOTIMPL )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static HRESULT WINAPI
IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
{
CFilterGraph_THIS(iface,mediaposition);
HRESULT hr = E_NOTIMPL;
HRESULT hrFilter;
DWORD n;
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( This->m_pActiveFilters[n].pPosition != NULL )
{
hrFilter = IMediaPosition_get_CurrentPosition( This->m_pActiveFilters[n].pPosition, prefTime );
if ( hr == E_NOTIMPL )
{
hr = hrFilter;
}
else
if ( hrFilter != E_NOTIMPL )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static HRESULT WINAPI
IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
{
CFilterGraph_THIS(iface,mediaposition);
HRESULT hr = E_NOTIMPL;
HRESULT hrFilter;
DWORD n;
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( This->m_pActiveFilters[n].pPosition != NULL )
{
hrFilter = IMediaPosition_get_StopTime( This->m_pActiveFilters[n].pPosition, prefTime );
if ( hr == E_NOTIMPL )
{
hr = hrFilter;
}
else
if ( hrFilter != E_NOTIMPL )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static HRESULT WINAPI
IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
{
CFilterGraph_THIS(iface,mediaposition);
HRESULT hr = E_NOTIMPL;
HRESULT hrFilter;
DWORD n;
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( This->m_pActiveFilters[n].pPosition != NULL )
{
hrFilter = IMediaPosition_put_StopTime( This->m_pActiveFilters[n].pPosition, refTime );
if ( hr == E_NOTIMPL )
{
hr = hrFilter;
}
else
if ( hrFilter != E_NOTIMPL )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static HRESULT WINAPI
IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
{
CFilterGraph_THIS(iface,mediaposition);
HRESULT hr = E_NOTIMPL;
HRESULT hrFilter;
DWORD n;
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( This->m_pActiveFilters[n].pPosition != NULL )
{
hrFilter = IMediaPosition_get_PrerollTime( This->m_pActiveFilters[n].pPosition, prefTime );
if ( hr == E_NOTIMPL )
{
hr = hrFilter;
}
else
if ( hrFilter != E_NOTIMPL )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static HRESULT WINAPI
IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
{
CFilterGraph_THIS(iface,mediaposition);
HRESULT hr = E_NOTIMPL;
HRESULT hrFilter;
DWORD n;
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( This->m_pActiveFilters[n].pPosition != NULL )
{
hrFilter = IMediaPosition_put_PrerollTime( This->m_pActiveFilters[n].pPosition, refTime );
if ( hr == E_NOTIMPL )
{
hr = hrFilter;
}
else
if ( hrFilter != E_NOTIMPL )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static HRESULT WINAPI
IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
{
CFilterGraph_THIS(iface,mediaposition);
HRESULT hr = E_NOTIMPL;
HRESULT hrFilter;
DWORD n;
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( This->m_pActiveFilters[n].pPosition != NULL )
{
hrFilter = IMediaPosition_put_Rate( This->m_pActiveFilters[n].pPosition, dblRate );
if ( hr == E_NOTIMPL )
{
hr = hrFilter;
}
else
if ( hrFilter != E_NOTIMPL )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static HRESULT WINAPI
IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
{
CFilterGraph_THIS(iface,mediaposition);
HRESULT hr = E_NOTIMPL;
HRESULT hrFilter;
DWORD n;
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( This->m_pActiveFilters[n].pPosition != NULL )
{
hrFilter = IMediaPosition_get_Rate( This->m_pActiveFilters[n].pPosition, pdblRate );
if ( hr == E_NOTIMPL )
{
hr = hrFilter;
}
else
if ( hrFilter != E_NOTIMPL )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static HRESULT WINAPI
IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
{
CFilterGraph_THIS(iface,mediaposition);
HRESULT hr = E_NOTIMPL;
HRESULT hrFilter;
DWORD n;
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( This->m_pActiveFilters[n].pPosition != NULL )
{
hrFilter = IMediaPosition_CanSeekForward( This->m_pActiveFilters[n].pPosition, pCanSeek );
if ( hr == E_NOTIMPL )
{
hr = hrFilter;
}
else
if ( hrFilter != E_NOTIMPL )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
static HRESULT WINAPI
IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
{
CFilterGraph_THIS(iface,mediaposition);
HRESULT hr = E_NOTIMPL;
HRESULT hrFilter;
DWORD n;
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
EnterCriticalSection( &This->m_csFilters );
for ( n = 0; n < This->m_cActiveFilters; n++ )
{
if ( This->m_pActiveFilters[n].pPosition != NULL )
{
hrFilter = IMediaPosition_CanSeekBackward( This->m_pActiveFilters[n].pPosition, pCanSeek );
if ( hr == E_NOTIMPL )
{
hr = hrFilter;
}
else
if ( hrFilter != E_NOTIMPL )
{
if ( SUCCEEDED(hr) )
hr = hrFilter;
}
}
}
LeaveCriticalSection( &This->m_csFilters );
return hr;
}
......
......@@ -90,6 +90,7 @@ typedef struct
static const QUARTZ_CLASSENTRY QUARTZ_ClassList[] =
{
{ &CLSID_FilterGraph, &QUARTZ_CreateFilterGraph },
{ &CLSID_FilterGraphNoThread, &QUARTZ_CreateFilterGraph }, /* FIXME? */
{ &CLSID_SystemClock, &QUARTZ_CreateSystemClock },
{ &CLSID_MemoryAllocator, &QUARTZ_CreateMemoryAllocator },
{ &CLSID_SystemDeviceEnum, &QUARTZ_CreateSystemDeviceEnum },
......
......@@ -61,7 +61,6 @@ HRESULT QUARTZ_MediaType_Copy(
pmtDst->pbFormat = (BYTE*)CoTaskMemAlloc( pmtSrc->cbFormat );
if ( pmtDst->pbFormat == NULL )
{
CoTaskMemFree( pmtDst );
return E_OUTOFMEMORY;
}
memcpy( pmtDst->pbFormat, pmtSrc->pbFormat, pmtSrc->cbFormat );
......
......@@ -41,6 +41,7 @@ struct CParserImpl
CParserInPinImpl* m_pInPin;
ULONG m_cOutStreams;
CParserOutPinImpl** m_ppOutPins;
GUID m_guidTimeFormat;
CRITICAL_SECTION m_csParser;
IAsyncReader* m_pReader;
......@@ -86,6 +87,7 @@ struct CParserOutPinImpl
LONG m_lReqLength;
REFERENCE_TIME m_rtReqStart;
REFERENCE_TIME m_rtReqStop;
DWORD m_dwSampleFlags;
};
......@@ -99,7 +101,7 @@ struct ParserHandlers
HRESULT (*pCheckStreamType)( CParserImpl* pImpl, ULONG nStreamIndex, const AM_MEDIA_TYPE* pmt );
HRESULT (*pGetAllocProp)( CParserImpl* pImpl, ALLOCATOR_PROPERTIES* pReqProp );
/* S_OK - ok, S_FALSE - end of stream */
HRESULT (*pGetNextRequest)( CParserImpl* pImpl, ULONG* pnStreamIndex, LONGLONG* pllStart, LONG* plLength, REFERENCE_TIME* prtStart, REFERENCE_TIME* prtStop );
HRESULT (*pGetNextRequest)( CParserImpl* pImpl, ULONG* pnStreamIndex, LONGLONG* pllStart, LONG* plLength, REFERENCE_TIME* prtStart, REFERENCE_TIME* prtStop, DWORD* pdwSampleFlags );
HRESULT (*pProcessSample)( CParserImpl* pImpl, ULONG nStreamIndex, LONGLONG llStart, LONG lLength, IMediaSample* pSample );
/* for IQualityControl */
......@@ -111,11 +113,9 @@ struct ParserHandlers
HRESULT (*pGetCurPos)( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllPos );
HRESULT (*pSetCurPos)( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG llPos );
HRESULT (*pGetDuration)( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllDuration );
HRESULT (*pSetDuration)( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG llDuration );
HRESULT (*pGetStopPos)( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllPos );
HRESULT (*pSetStopPos)( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG llPos );
HRESULT (*pGetPreroll)( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllPreroll );
HRESULT (*pSetPreroll)( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG llPreroll );
};
#define CParserImpl_THIS(iface,member) CParserImpl* This = ((CParserImpl*)(((char*)iface)-offsetof(CParserImpl,member)))
......
......@@ -29,5 +29,10 @@ void* QUARTZ_ReallocMem( void* pMem, DWORD dwSize );
#define QUARTZ_TIMEUNITS ((LONGLONG)10000000)
/* undocument APIs. */
LONG WINAPI QUARTZ_AmpFactorToDB( LONG amp );
LONG WINAPI QUARTZ_DBToAmpFactor( LONG dB );
#endif /* QUARTZ_PRIVATE_H */
......@@ -180,8 +180,10 @@ typedef struct CWavParseImpl
WAVEFORMATEX* pFmt;
DWORD dwBlockSize;
LONGLONG llDataStart;
LONGLONG llBytesStop;
LONGLONG llBytesTotal;
LONGLONG llBytesProcessed;
BOOL bDataDiscontinuity;
WavParseFmtType iFmtType;
} CWavParseImpl;
......@@ -330,8 +332,10 @@ static HRESULT CWavParseImpl_InitParser( CParserImpl* pImpl, ULONG* pcStreams )
This->pFmt = NULL;
This->dwBlockSize = 0;
This->llDataStart = 0;
This->llBytesStop = 0;
This->llBytesTotal = 0;
This->llBytesProcessed = 0;
This->bDataDiscontinuity = TRUE;
This->iFmtType = WaveParse_Native;
hr = IAsyncReader_SyncRead( pImpl->m_pReader, 0, 12, header );
......@@ -370,6 +374,8 @@ static HRESULT CWavParseImpl_InitParser( CParserImpl* pImpl, ULONG* pcStreams )
return hr;
}
This->llBytesStop = This->llBytesTotal;
/* initialized successfully. */
*pcStreams = 1;
......@@ -461,7 +467,7 @@ static HRESULT CWavParseImpl_GetAllocProp( CParserImpl* pImpl, ALLOCATOR_PROPERT
return NOERROR;
}
static HRESULT CWavParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStreamIndex, LONGLONG* pllStart, LONG* plLength, REFERENCE_TIME* prtStart, REFERENCE_TIME* prtStop )
static HRESULT CWavParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStreamIndex, LONGLONG* pllStart, LONG* plLength, REFERENCE_TIME* prtStart, REFERENCE_TIME* prtStop, DWORD* pdwSampleFlags )
{
CWavParseImpl* This = (CWavParseImpl*)pImpl->m_pUserData;
LONGLONG llAvail;
......@@ -472,8 +478,14 @@ static HRESULT CWavParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStream
if ( This == NULL || This->pFmt == NULL )
return E_UNEXPECTED;
*pdwSampleFlags = AM_SAMPLE_SPLICEPOINT;
if ( This->bDataDiscontinuity )
{
*pdwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
This->bDataDiscontinuity = FALSE;
}
llAvail = This->llBytesTotal - This->llBytesProcessed;
llAvail = This->llBytesStop - This->llBytesProcessed;
if ( llAvail > (LONGLONG)This->dwBlockSize )
llAvail = (LONGLONG)This->dwBlockSize;
llStart = This->llDataStart + This->llBytesProcessed;
......@@ -529,6 +541,172 @@ static HRESULT CWavParseImpl_ProcessSample( CParserImpl* pImpl, ULONG nStreamInd
return NOERROR;
}
/***************************************************************************/
static HRESULT CWavParseImpl_GetSeekingCaps( CParserImpl* pImpl, DWORD* pdwCaps )
{
CWavParseImpl* This = (CWavParseImpl*)pImpl->m_pUserData;
TRACE("(%p,%p)\n",This,pdwCaps);
*pdwCaps =
AM_SEEKING_CanSeekAbsolute |
AM_SEEKING_CanSeekForwards |
AM_SEEKING_CanSeekBackwards |
AM_SEEKING_CanGetCurrentPos |
AM_SEEKING_CanGetStopPos |
AM_SEEKING_CanGetDuration;
return S_OK;
}
static HRESULT CWavParseImpl_IsTimeFormatSupported( CParserImpl* pImpl, const GUID* pTimeFormat )
{
CWavParseImpl* This = (CWavParseImpl*)pImpl->m_pUserData;
TRACE("(%p,%s)\n",This,debugstr_guid(pTimeFormat));
if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
return S_OK;
return S_FALSE;
}
static HRESULT CWavParseImpl_GetCurPos( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllPos )
{
CWavParseImpl* This = (CWavParseImpl*)pImpl->m_pUserData;
TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);
if ( This == NULL || This->pFmt == NULL )
return E_UNEXPECTED;
if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
{
if ( This->pFmt->nAvgBytesPerSec == 0 )
return E_FAIL;
*pllPos = This->llBytesProcessed * QUARTZ_TIMEUNITS / (LONGLONG)This->pFmt->nAvgBytesPerSec;
TRACE("curpos %f\n",(double)(*pllPos/QUARTZ_TIMEUNITS));
return S_OK;
}
return E_NOTIMPL;
}
static HRESULT CWavParseImpl_SetCurPos( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG llPos )
{
CWavParseImpl* This = (CWavParseImpl*)pImpl->m_pUserData;
LONGLONG llBytesCur;
TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);
if ( This == NULL || This->pFmt == NULL )
return E_UNEXPECTED;
if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
{
if ( This->pFmt->nAvgBytesPerSec == 0 )
return E_FAIL;
llBytesCur = llPos * This->pFmt->nAvgBytesPerSec / QUARTZ_TIMEUNITS;
if ( llBytesCur > This->llBytesTotal )
llBytesCur = This->llBytesTotal;
This->llBytesProcessed = llBytesCur;
This->bDataDiscontinuity = TRUE;
return S_OK;
}
return E_NOTIMPL;
}
static HRESULT CWavParseImpl_GetDuration( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllDuration )
{
CWavParseImpl* This = (CWavParseImpl*)pImpl->m_pUserData;
TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);
if ( This == NULL || This->pFmt == NULL )
return E_UNEXPECTED;
if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
{
if ( This->pFmt->nAvgBytesPerSec == 0 )
return E_FAIL;
*pllDuration = This->llBytesTotal * QUARTZ_TIMEUNITS / (LONGLONG)This->pFmt->nAvgBytesPerSec;
TRACE("duration %f\n",(double)(*pllDuration/QUARTZ_TIMEUNITS));
return S_OK;
}
return E_NOTIMPL;
}
static HRESULT CWavParseImpl_GetStopPos( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllPos )
{
CWavParseImpl* This = (CWavParseImpl*)pImpl->m_pUserData;
TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);
if ( This == NULL || This->pFmt == NULL )
return E_UNEXPECTED;
if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
{
if ( This->pFmt->nAvgBytesPerSec == 0 )
return E_FAIL;
*pllPos = This->llBytesStop * QUARTZ_TIMEUNITS / (LONGLONG)This->pFmt->nAvgBytesPerSec;
return S_OK;
}
return E_NOTIMPL;
}
static HRESULT CWavParseImpl_SetStopPos( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG llPos )
{
CWavParseImpl* This = (CWavParseImpl*)pImpl->m_pUserData;
LONGLONG llBytesStop;
TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);
if ( This == NULL || This->pFmt == NULL )
return E_UNEXPECTED;
if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
{
if ( This->pFmt->nAvgBytesPerSec == 0 )
return E_FAIL;
llBytesStop = llPos * This->pFmt->nAvgBytesPerSec / QUARTZ_TIMEUNITS;
if ( llBytesStop > This->llBytesTotal )
llBytesStop = This->llBytesTotal;
This->llBytesStop = llBytesStop;
return S_OK;
}
return E_NOTIMPL;
}
static HRESULT CWavParseImpl_GetPreroll( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllPreroll )
{
CWavParseImpl* This = (CWavParseImpl*)pImpl->m_pUserData;
TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);
if ( This == NULL || This->pFmt == NULL )
return E_UNEXPECTED;
if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
{
*pllPreroll = 0;
return S_OK;
}
return E_NOTIMPL;
}
/***************************************************************************/
static const struct ParserHandlers CWavParseImpl_Handlers =
{
......@@ -545,16 +723,14 @@ static const struct ParserHandlers CWavParseImpl_Handlers =
NULL, /* pQualityNotify */
/* for seeking */
NULL, /* pGetSeekingCaps */
NULL, /* pIsTimeFormatSupported */
NULL, /* pGetCurPos */
NULL, /* pSetCurPos */
NULL, /* pGetDuration */
NULL, /* pSetDuration */
NULL, /* pGetStopPos */
NULL, /* pSetStopPos */
NULL, /* pGetPreroll */
NULL, /* pSetPreroll */
CWavParseImpl_GetSeekingCaps,
CWavParseImpl_IsTimeFormatSupported,
CWavParseImpl_GetCurPos,
CWavParseImpl_SetCurPos,
CWavParseImpl_GetDuration,
CWavParseImpl_GetStopPos,
CWavParseImpl_SetStopPos,
CWavParseImpl_GetPreroll,
};
HRESULT QUARTZ_CreateWaveParser(IUnknown* punkOuter,void** ppobj)
......
......@@ -208,49 +208,56 @@ static HRESULT CTransformBaseInPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSampl
if ( This->pFilter->m_bInFlush )
return S_FALSE;
if ( This->meminput.pAllocator != This->pFilter->m_pOutPinAllocator )
if ( This->pFilter->m_pHandler->pProcessReceive != NULL )
{
if ( This->pFilter->m_pSample == NULL )
hr = This->pFilter->m_pHandler->pProcessReceive( This->pFilter, pSample );
}
else
{
if ( This->meminput.pAllocator != This->pFilter->m_pOutPinAllocator )
{
hr = IMemAllocator_GetBuffer( This->pFilter->m_pOutPinAllocator, &This->pFilter->m_pSample, NULL, NULL, 0 );
if ( This->pFilter->m_pSample == NULL )
{
hr = IMemAllocator_GetBuffer( This->pFilter->m_pOutPinAllocator, &This->pFilter->m_pSample, NULL, NULL, 0 );
if ( FAILED(hr) )
goto end;
}
hr = QUARTZ_IMediaSample_Copy(
This->pFilter->m_pSample, pSample, This->pFilter->m_bPreCopy );
if ( FAILED(hr) )
goto end;
}
hr = QUARTZ_IMediaSample_Copy(
This->pFilter->m_pSample, pSample, This->pFilter->m_bPreCopy );
if ( FAILED(hr) )
goto end;
}
if ( This->pFilter->m_bPreCopy )
hr = This->pFilter->m_pHandler->pTransform( This->pFilter, This->pFilter->m_pSample, NULL );
else
hr = This->pFilter->m_pHandler->pTransform( This->pFilter, pSample, This->pFilter->m_pSample );
if ( FAILED(hr) )
goto end;
if ( This->pFilter->m_bPreCopy )
hr = This->pFilter->m_pHandler->pTransform( This->pFilter, This->pFilter->m_pSample, NULL );
else
hr = This->pFilter->m_pHandler->pTransform( This->pFilter, pSample, This->pFilter->m_pSample );
if ( hr == NOERROR )
{
hr = CPinBaseImpl_SendSample(&This->pFilter->pOutPin->pin,This->pFilter->m_pSample);
if ( FAILED(hr) )
goto end;
}
hr = NOERROR;
end:
if ( !This->pFilter->m_bReuseSample )
{
if ( This->pFilter->m_pSample != NULL )
if ( hr == NOERROR )
{
IMediaSample_Release( This->pFilter->m_pSample );
This->pFilter->m_pSample = NULL;
hr = CPinBaseImpl_SendSample(&This->pFilter->pOutPin->pin,This->pFilter->m_pSample);
if ( FAILED(hr) )
goto end;
}
}
if ( FAILED(hr) )
{
/* Notify(ABORT) */
hr = NOERROR;
end:
if ( !This->pFilter->m_bReuseSample )
{
if ( This->pFilter->m_pSample != NULL )
{
IMediaSample_Release( This->pFilter->m_pSample );
This->pFilter->m_pSample = NULL;
}
}
if ( FAILED(hr) )
{
/* Notify(ABORT) */
}
}
return hr;
......
......@@ -88,6 +88,7 @@ struct TransformBaseHandlers
/* prepare the filter */
HRESULT (*pBeginTransform)( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut, BOOL bReuseSample );
/* process a sample */
HRESULT (*pProcessReceive)( CTransformBaseImpl* pImpl, IMediaSample* pSampIn ); /* override Transform */
HRESULT (*pTransform)( CTransformBaseImpl* pImpl, IMediaSample* pSampIn, IMediaSample* pSampOut );
/* unprepare the filter */
HRESULT (*pEndTransform)( CTransformBaseImpl* pImpl );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment