From bc7d0272b322bbf843e19998df76089e6a581513 Mon Sep 17 00:00:00 2001 From: Hidenori Takeshima Date: Sun, 14 Oct 2001 16:13:14 +0000 Subject: [PATCH] Started implementing AVI splitter. Implemented AsyncSource. Merged some C sources. Fixed some bugs. --- dlls/quartz/Makefile.in | 6 +- dlls/quartz/asyncsrc.c | 633 +++++++++++++++++++++++++++++++++++---- dlls/quartz/asyncsrc.h | 41 ++- dlls/quartz/audioutl.c | 63 ++++ dlls/quartz/audioutl.h | 11 + dlls/quartz/audren.c | 2 - dlls/quartz/aviparse.c | 695 +++++++++++++++++++++++++++++++++++++++++++ dlls/quartz/basefilt.c | 6 +- dlls/quartz/basepin.c | 10 +- dlls/quartz/complist.c | 55 +++- dlls/quartz/complist.h | 7 + dlls/quartz/devenum.c | 9 +- dlls/quartz/devmon.c | 4 +- dlls/quartz/enumunk.c | 7 +- dlls/quartz/fgevent.c | 2 - dlls/quartz/fgidisp.c | 129 -------- dlls/quartz/fgpass.c | 2 - dlls/quartz/fgraph.c | 108 ++++++- dlls/quartz/fgraph.h | 1 - dlls/quartz/fmap.c | 220 +++++++++++++- dlls/quartz/fmap.h | 34 ++- dlls/quartz/fmap2.c | 237 --------------- dlls/quartz/fmap2.h | 38 --- dlls/quartz/ifgraph.c | 310 ++++++++++++++++++- dlls/quartz/igconfig.c | 209 ------------- dlls/quartz/igrver.c | 109 ------- dlls/quartz/imcntl.c | 2 - dlls/quartz/imfilter.c | 2 - dlls/quartz/impos.c | 2 - dlls/quartz/imseek.c | 2 - dlls/quartz/main.c | 8 +- dlls/quartz/memalloc.c | 1 - dlls/quartz/mtype.c | 104 ++++++- dlls/quartz/mtype.h | 3 + dlls/quartz/parser.c | 8 +- dlls/quartz/parser.h | 21 +- dlls/quartz/quartz_private.h | 2 + dlls/quartz/regsvr.c | 21 +- dlls/quartz/sample.c | 1 - dlls/quartz/seekpass.c | 1 - dlls/quartz/sysclock.c | 1 - dlls/quartz/vidren.c | 2 - dlls/quartz/wavparse.c | 108 ++++++- include/amvideo.h | 1 - include/control.h | 2 - include/strmif.h | 5 +- 46 files changed, 2333 insertions(+), 912 deletions(-) create mode 100644 dlls/quartz/audioutl.c create mode 100644 dlls/quartz/audioutl.h create mode 100644 dlls/quartz/aviparse.c delete mode 100644 dlls/quartz/fgidisp.c delete mode 100644 dlls/quartz/fmap2.c delete mode 100644 dlls/quartz/fmap2.h delete mode 100644 dlls/quartz/igconfig.c delete mode 100644 dlls/quartz/igrver.c diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in index 20756447b05..2ebbea5b809 100644 --- a/dlls/quartz/Makefile.in +++ b/dlls/quartz/Makefile.in @@ -11,7 +11,9 @@ SYMBOLFILE = $(MODULE).tmp.o C_SRCS = \ amundoc.c \ asyncsrc.c \ + audioutl.c \ audren.c \ + aviparse.c \ basefilt.c \ basepin.c \ complist.c \ @@ -19,14 +21,10 @@ C_SRCS = \ devmon.c \ enumunk.c \ fgevent.c \ - fgidisp.c \ fgpass.c \ fgraph.c \ fmap.c \ - fmap2.c \ ifgraph.c \ - igconfig.c \ - igrver.c \ imcntl.c \ imfilter.c \ impos.c \ diff --git a/dlls/quartz/asyncsrc.c b/dlls/quartz/asyncsrc.c index a5cd0d0d6a1..fcc54b35abf 100644 --- a/dlls/quartz/asyncsrc.c +++ b/dlls/quartz/asyncsrc.c @@ -1,7 +1,7 @@ /* * Implements Asynchronous File/URL Source. * - * FIXME - not work yet. + * FIXME - URL source is not implemented yet. * * hidenori@a2.ctktv.ne.jp */ @@ -13,7 +13,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" #include "strmif.h" #include "vfwmsgs.h" #include "uuids.h" @@ -26,41 +25,192 @@ DEFAULT_DEBUG_CHANNEL(quartz); #include "memalloc.h" + +const WCHAR QUARTZ_wszAsyncFileSourceName[] = +{'F','i','l','e',' ','S','o','u','r','c','e',' ','(','A','s','y','n','c','.',')',0}; +const WCHAR QUARTZ_wszAsyncFileSourcePinName[] = +{'O','u','t',0}; +const WCHAR QUARTZ_wszAsyncURLSourceName[] = +{'F','i','l','e',' ','S','o','u','r','c','e',' ','(','U','R','L',')',0}; +const WCHAR QUARTZ_wszAsyncURLSourcePinName[] = +{'O','u','t',0}; + + + /*************************************************************************** * * CAsyncReaderImpl internal methods * */ +static +AsyncSourceRequest* CAsyncReaderImpl_AllocRequest( CAsyncReaderImpl* This ) +{ + AsyncSourceRequest* pReq; + + EnterCriticalSection( &This->m_csFree ); + pReq = This->m_pFreeFirst; + if ( pReq != NULL ) + This->m_pFreeFirst = pReq->pNext; + LeaveCriticalSection( &This->m_csFree ); + + if ( pReq == NULL ) + { + pReq = (AsyncSourceRequest*)QUARTZ_AllocMem( + sizeof(AsyncSourceRequest) ); + if ( pReq == NULL ) + return NULL; + } + + pReq->pNext = NULL; + pReq->llStart = 0; + pReq->lLength = 0; + pReq->lActual = 0; + pReq->pBuf = NULL; + pReq->pSample = NULL; + pReq->dwContext = 0; + + return pReq; +} + +static +void CAsyncReaderImpl_FreeRequest( CAsyncReaderImpl* This, AsyncSourceRequest* pReq, BOOL bReleaseMem ) +{ + if ( !bReleaseMem ) + { + EnterCriticalSection( &This->m_csFree ); + pReq->pNext = This->m_pFreeFirst; + This->m_pFreeFirst = pReq; + LeaveCriticalSection( &This->m_csFree ); + } + else + { + QUARTZ_FreeMem( pReq ); + } +} + +static +AsyncSourceRequest* CAsyncReaderImpl_GetRequest( CAsyncReaderImpl* This ) +{ + AsyncSourceRequest* pReq; + + EnterCriticalSection( &This->m_csRequest ); + pReq = This->m_pRequestFirst; + if ( pReq != NULL ) + This->m_pRequestFirst = pReq->pNext; + LeaveCriticalSection( &This->m_csRequest ); + + return pReq; +} + +static +AsyncSourceRequest* CAsyncReaderImpl_GetReply( CAsyncReaderImpl* This ) +{ + AsyncSourceRequest* pReq; + + EnterCriticalSection( &This->m_csReply ); + pReq = This->m_pReplyFirst; + if ( pReq != NULL ) + This->m_pReplyFirst = pReq->pNext; + LeaveCriticalSection( &This->m_csReply ); + + return pReq; +} + +static +void CAsyncReaderImpl_PostRequest( CAsyncReaderImpl* This, AsyncSourceRequest* pReq ) +{ + /* FIXME - add to tail */ + EnterCriticalSection( &This->m_csRequest ); + pReq->pNext = This->m_pRequestFirst; + This->m_pRequestFirst = pReq; + if ( This->m_hEventReqQueued != (HANDLE)NULL ) + SetEvent( This->m_hEventReqQueued ); + LeaveCriticalSection( &This->m_csRequest ); +} + +static +void CAsyncReaderImpl_PostReply( CAsyncReaderImpl* This, AsyncSourceRequest* pReq ) +{ + /* FIXME - add to tail */ + EnterCriticalSection( &This->m_csReply ); + pReq->pNext = This->m_pReplyFirst; + This->m_pReplyFirst = pReq; + if ( This->m_hEventSampQueued != (HANDLE)NULL ) + SetEvent( This->m_hEventSampQueued ); + LeaveCriticalSection( &This->m_csReply ); +} + +static +void CAsyncReaderImpl_ReleaseReqList( CAsyncReaderImpl* This, AsyncSourceRequest* pReq, BOOL bReleaseMem ) +{ + AsyncSourceRequest* pReqNext; + + while ( pReq != NULL ) + { + pReqNext = pReq->pNext; + CAsyncReaderImpl_FreeRequest(This,pReq,bReleaseMem); + pReq = pReqNext; + } +} + static DWORD WINAPI CAsyncReaderImpl_ThreadEntry( LPVOID pv ) { CAsyncReaderImpl* This = (CAsyncReaderImpl*)pv; HANDLE hWaitEvents[2]; - HANDLE hReadEvents[2]; + HRESULT hr; DWORD dwRes; + AsyncSourceRequest* pReq = NULL; SetEvent( This->m_hEventInit ); hWaitEvents[0] = This->m_hEventReqQueued; - hWaitEvents[1] = This->m_hEventAbort; + hWaitEvents[1] = This->m_hEventCancel; - hReadEvents[0] = This->m_hEventSampQueued; - hReadEvents[1] = This->m_hEventAbort; + TRACE("enter message loop.\n"); while ( 1 ) { - dwRes = WaitForMultipleObjects(2,hWaitEvents,FALSE,INFINITE); - if ( dwRes != WAIT_OBJECT_0 ) - break; + ResetEvent( This->m_hEventReqQueued ); + pReq = CAsyncReaderImpl_GetRequest(This); + if ( pReq == NULL ) + { + dwRes = WaitForMultipleObjects(2,hWaitEvents,FALSE,INFINITE); + if ( dwRes != WAIT_OBJECT_0 ) + { + if ( This->m_bAbortThread ) + break; + } + continue; + } - /* FIXME - process a queued request */ + /* process a queued request */ + EnterCriticalSection( &This->m_csReader ); + hr = This->pSource->m_pHandler->pRead( This->pSource, pReq->llStart, pReq->lLength, pReq->pBuf, &pReq->lActual, This->m_hEventCancel ); + LeaveCriticalSection( &This->m_csReader ); - dwRes = WaitForMultipleObjects(2,hReadEvents,FALSE,INFINITE); - if ( dwRes != WAIT_OBJECT_0 ) + if ( FAILED(hr) ) + { + /* Notify(ABORT) */ break; + } + if ( hr != S_OK ) + { + if ( This->m_bAbortThread ) + break; + ResetEvent( This->m_hEventCancel ); + } + + CAsyncReaderImpl_PostReply( This, pReq ); + SetEvent( This->m_hEventSampQueued ); + pReq = NULL; } + if ( pReq != NULL ) + CAsyncReaderImpl_PostRequest( This, pReq ); + + SetEvent( This->m_hEventSampQueued ); return 0; } @@ -72,18 +222,18 @@ CAsyncReaderImpl_BeginThread( CAsyncReaderImpl* This ) HANDLE hEvents[2]; if ( This->m_hEventInit != (HANDLE)NULL || - This->m_hEventAbort != (HANDLE)NULL || + This->m_hEventCancel != (HANDLE)NULL || This->m_hEventReqQueued != (HANDLE)NULL || This->m_hEventSampQueued != (HANDLE)NULL || - This->m_hEventCompletion != (HANDLE)NULL || This->m_hThread != (HANDLE)NULL ) return E_UNEXPECTED; + This->m_bAbortThread = FALSE; This->m_hEventInit = CreateEventA(NULL,TRUE,FALSE,NULL); if ( This->m_hEventInit == (HANDLE)NULL ) return E_OUTOFMEMORY; - This->m_hEventAbort = CreateEventA(NULL,TRUE,FALSE,NULL); - if ( This->m_hEventAbort == (HANDLE)NULL ) + This->m_hEventCancel = CreateEventA(NULL,TRUE,FALSE,NULL); + if ( This->m_hEventCancel == (HANDLE)NULL ) return E_OUTOFMEMORY; This->m_hEventReqQueued = CreateEventA(NULL,TRUE,FALSE,NULL); if ( This->m_hEventReqQueued == (HANDLE)NULL ) @@ -91,9 +241,6 @@ CAsyncReaderImpl_BeginThread( CAsyncReaderImpl* This ) This->m_hEventSampQueued = CreateEventA(NULL,TRUE,FALSE,NULL); if ( This->m_hEventSampQueued == (HANDLE)NULL ) return E_OUTOFMEMORY; - This->m_hEventCompletion = CreateEventA(NULL,TRUE,FALSE,NULL); - if ( This->m_hEventCompletion == (HANDLE)NULL ) - return E_OUTOFMEMORY; /* create the processing thread. */ This->m_hThread = CreateThread( @@ -119,9 +266,13 @@ CAsyncReaderImpl_EndThread( CAsyncReaderImpl* This ) { if ( This->m_hThread != (HANDLE)NULL ) { - SetEvent( This->m_hEventAbort ); - - WaitForSingleObject( This->m_hThread, INFINITE ); + while ( 1 ) + { + This->m_bAbortThread = TRUE; + SetEvent( This->m_hEventCancel ); + if ( WaitForSingleObject( This->m_hThread, 100 ) == WAIT_OBJECT_0 ) + break; + } CloseHandle( This->m_hThread ); This->m_hThread = (HANDLE)NULL; } @@ -130,10 +281,10 @@ CAsyncReaderImpl_EndThread( CAsyncReaderImpl* This ) CloseHandle( This->m_hEventInit ); This->m_hEventInit = (HANDLE)NULL; } - if ( This->m_hEventAbort != (HANDLE)NULL ) + if ( This->m_hEventCancel != (HANDLE)NULL ) { - CloseHandle( This->m_hEventAbort ); - This->m_hEventAbort = (HANDLE)NULL; + CloseHandle( This->m_hEventCancel ); + This->m_hEventCancel = (HANDLE)NULL; } if ( This->m_hEventReqQueued != (HANDLE)NULL ) { @@ -145,11 +296,6 @@ CAsyncReaderImpl_EndThread( CAsyncReaderImpl* This ) CloseHandle( This->m_hEventSampQueued ); This->m_hEventSampQueued = (HANDLE)NULL; } - if ( This->m_hEventCompletion != (HANDLE)NULL ) - { - CloseHandle( This->m_hEventCompletion ); - This->m_hEventCompletion = (HANDLE)NULL; - } } /*************************************************************************** @@ -233,52 +379,146 @@ static HRESULT WINAPI CAsyncReaderImpl_fnRequest(IAsyncReader* iface,IMediaSample* pSample,DWORD_PTR dwContext) { ICOM_THIS(CAsyncReaderImpl,iface); + HRESULT hr = NOERROR; + REFERENCE_TIME rtStart; + REFERENCE_TIME rtEnd; + AsyncSourceRequest* pReq; + BYTE* pData = NULL; - FIXME("(%p)->() stub!\n",This); + TRACE("(%p)->(%p,%u)\n",This,pSample,dwContext); + + hr = IMediaSample_GetPointer(pSample,&pData); + if ( SUCCEEDED(hr) ) + hr = IMediaSample_GetTime(pSample,&rtStart,&rtEnd); + if ( FAILED(hr) ) + return hr; - EnterCriticalSection( This->pcsReader ); - LeaveCriticalSection( This->pcsReader ); + pReq = CAsyncReaderImpl_AllocRequest(This); + if ( pReq == NULL ) + return E_OUTOFMEMORY; - return E_NOTIMPL; + pReq->llStart = rtStart / QUARTZ_TIMEUNITS; + pReq->lLength = (LONG)(rtEnd / QUARTZ_TIMEUNITS - rtStart / QUARTZ_TIMEUNITS); + pReq->lActual = 0; + pReq->pBuf = pData; + pReq->pSample = pSample; + pReq->dwContext = dwContext; + CAsyncReaderImpl_PostRequest( This, pReq ); + + return NOERROR; } static HRESULT WINAPI -CAsyncReaderImpl_fnWaitForNext(IAsyncReader* iface,DWORD dwTimeout,IMediaSample** pSample,DWORD_PTR* pdwContext) +CAsyncReaderImpl_fnWaitForNext(IAsyncReader* iface,DWORD dwTimeout,IMediaSample** ppSample,DWORD_PTR* pdwContext) { ICOM_THIS(CAsyncReaderImpl,iface); + HRESULT hr = NOERROR; + DWORD dwRes; + AsyncSourceRequest* pReq; + REFERENCE_TIME rtStart; + REFERENCE_TIME rtEnd; - FIXME("(%p)->() stub!\n",This); + TRACE("(%p)->(%lu,%p,%p)\n",This,dwTimeout,ppSample,pdwContext); - EnterCriticalSection( This->pcsReader ); - LeaveCriticalSection( This->pcsReader ); + EnterCriticalSection( &This->m_csRequest ); + if ( This->m_bInFlushing ) + hr = VFW_E_TIMEOUT; + LeaveCriticalSection( &This->m_csRequest ); - return E_NOTIMPL; + if ( hr == NOERROR ) + { + ResetEvent( This->m_hEventSampQueued ); + pReq = CAsyncReaderImpl_GetReply(This); + if ( pReq == NULL ) + { + dwRes = WaitForSingleObject( This->m_hEventSampQueued, dwTimeout ); + if ( dwRes == WAIT_OBJECT_0 ) + pReq = CAsyncReaderImpl_GetReply(This); + } + if ( pReq != NULL ) + { + hr = IMediaSample_SetActualDataLength(pReq->pSample,pReq->lActual); + if ( hr == S_OK ) + { + rtStart = pReq->llStart * QUARTZ_TIMEUNITS; + rtEnd = (pReq->llStart + pReq->lActual) * QUARTZ_TIMEUNITS; + hr = IMediaSample_SetTime(pReq->pSample,&rtStart,&rtEnd); + } + *ppSample = pReq->pSample; + *pdwContext = pReq->dwContext; + if ( hr == S_OK && pReq->lActual != pReq->lLength ) + hr = S_FALSE; + } + else + { + hr = VFW_E_TIMEOUT; + } + } + + return hr; } static HRESULT WINAPI CAsyncReaderImpl_fnSyncReadAligned(IAsyncReader* iface,IMediaSample* pSample) { ICOM_THIS(CAsyncReaderImpl,iface); + HRESULT hr; + REFERENCE_TIME rtStart; + REFERENCE_TIME rtEnd; + BYTE* pData = NULL; + LONGLONG llStart; + LONG lLength; + LONG lActual; - FIXME("(%p)->() stub!\n",This); + TRACE("(%p)->(%p)\n",This,pSample); - EnterCriticalSection( This->pcsReader ); - LeaveCriticalSection( This->pcsReader ); + hr = IMediaSample_GetPointer(pSample,&pData); + if ( SUCCEEDED(hr) ) + hr = IMediaSample_GetTime(pSample,&rtStart,&rtEnd); + if ( FAILED(hr) ) + return hr; - return E_NOTIMPL; + llStart = rtStart / QUARTZ_TIMEUNITS; + lLength = (LONG)(rtEnd / QUARTZ_TIMEUNITS - rtStart / QUARTZ_TIMEUNITS); + lActual = 0; + + EnterCriticalSection( &This->m_csReader ); + hr = This->pSource->m_pHandler->pRead( This->pSource, llStart, lLength, pData, &lActual, (HANDLE)NULL ); + LeaveCriticalSection( &This->m_csReader ); + + if ( hr == NOERROR ) + { + hr = IMediaSample_SetActualDataLength(pSample,lActual); + if ( hr == S_OK ) + { + rtStart = llStart * QUARTZ_TIMEUNITS; + rtEnd = (llStart + lActual) * QUARTZ_TIMEUNITS; + hr = IMediaSample_SetTime(pSample,&rtStart,&rtEnd); + } + if ( hr == S_OK && lActual != lLength ) + hr = S_FALSE; + } + + return hr; } static HRESULT WINAPI CAsyncReaderImpl_fnSyncRead(IAsyncReader* iface,LONGLONG llPosStart,LONG lLength,BYTE* pbBuf) { ICOM_THIS(CAsyncReaderImpl,iface); + HRESULT hr; + LONG lActual; - FIXME("(%p)->() stub!\n",This); + TRACE("(%p)->()\n",This); - EnterCriticalSection( This->pcsReader ); - LeaveCriticalSection( This->pcsReader ); + EnterCriticalSection( &This->m_csReader ); + hr = This->pSource->m_pHandler->pRead( This->pSource, llPosStart, lLength, pbBuf, &lActual, (HANDLE)NULL ); + LeaveCriticalSection( &This->m_csReader ); - return E_NOTIMPL; + if ( hr == S_OK && lLength != lActual ) + hr = S_FALSE; + + return hr; } static HRESULT WINAPI @@ -289,9 +529,7 @@ CAsyncReaderImpl_fnLength(IAsyncReader* iface,LONGLONG* pllTotal,LONGLONG* pllAv TRACE("(%p)->()\n",This); - EnterCriticalSection( This->pcsReader ); hr = This->pSource->m_pHandler->pGetLength( This->pSource, pllTotal, pllAvailable ); - LeaveCriticalSection( This->pcsReader ); return hr; } @@ -301,12 +539,15 @@ CAsyncReaderImpl_fnBeginFlush(IAsyncReader* iface) { ICOM_THIS(CAsyncReaderImpl,iface); - FIXME("(%p)->() stub!\n",This); + TRACE("(%p)->()\n",This); - EnterCriticalSection( This->pcsReader ); - LeaveCriticalSection( This->pcsReader ); + EnterCriticalSection( &This->m_csRequest ); + This->m_bInFlushing = TRUE; + SetEvent( This->m_hEventCancel ); + CAsyncReaderImpl_ReleaseReqList(This,This->m_pRequestFirst,FALSE); + LeaveCriticalSection( &This->m_csRequest ); - return E_NOTIMPL; + return NOERROR; } static HRESULT WINAPI @@ -314,12 +555,14 @@ CAsyncReaderImpl_fnEndFlush(IAsyncReader* iface) { ICOM_THIS(CAsyncReaderImpl,iface); - FIXME("(%p)->() stub!\n",This); + TRACE("(%p)->()\n",This); - EnterCriticalSection( This->pcsReader ); - LeaveCriticalSection( This->pcsReader ); + EnterCriticalSection( &This->m_csRequest ); + This->m_bInFlushing = FALSE; + ResetEvent( This->m_hEventCancel ); + LeaveCriticalSection( &This->m_csRequest ); - return E_NOTIMPL; + return NOERROR; } @@ -344,8 +587,7 @@ static ICOM_VTABLE(IAsyncReader) iasyncreader = HRESULT CAsyncReaderImpl_InitIAsyncReader( CAsyncReaderImpl* This, IUnknown* punkControl, - CAsyncSourceImpl* pSource, - CRITICAL_SECTION* pcsReader ) + CAsyncSourceImpl* pSource ) { TRACE("(%p,%p)\n",This,punkControl); @@ -358,13 +600,21 @@ HRESULT CAsyncReaderImpl_InitIAsyncReader( ICOM_VTBL(This) = &iasyncreader; This->punkControl = punkControl; This->pSource = pSource; - This->pcsReader = pcsReader; + This->m_bInFlushing = FALSE; + This->m_bAbortThread = FALSE; This->m_hEventInit = (HANDLE)NULL; - This->m_hEventAbort = (HANDLE)NULL; + This->m_hEventCancel = (HANDLE)NULL; This->m_hEventReqQueued = (HANDLE)NULL; This->m_hEventSampQueued = (HANDLE)NULL; - This->m_hEventCompletion = (HANDLE)NULL; This->m_hThread = (HANDLE)NULL; + This->m_pRequestFirst = NULL; + This->m_pReplyFirst = NULL; + This->m_pFreeFirst = NULL; + + InitializeCriticalSection( &This->m_csReader ); + InitializeCriticalSection( &This->m_csRequest ); + InitializeCriticalSection( &This->m_csReply ); + InitializeCriticalSection( &This->m_csFree ); return NOERROR; } @@ -373,6 +623,15 @@ void CAsyncReaderImpl_UninitIAsyncReader( CAsyncReaderImpl* This ) { TRACE("(%p)\n",This); + + CAsyncReaderImpl_ReleaseReqList(This,This->m_pRequestFirst,TRUE); + CAsyncReaderImpl_ReleaseReqList(This,This->m_pReplyFirst,TRUE); + CAsyncReaderImpl_ReleaseReqList(This,This->m_pFreeFirst,TRUE); + + DeleteCriticalSection( &This->m_csReader ); + DeleteCriticalSection( &This->m_csRequest ); + DeleteCriticalSection( &This->m_csReply ); + DeleteCriticalSection( &This->m_csFree ); } /*************************************************************************** @@ -450,6 +709,9 @@ CFileSourceFilterImpl_fnLoad(IFileSourceFilter* iface,LPCOLESTR pFileName,const if ( FAILED(hr) ) goto err; + This->pSource->pPin->pin.pmtAcceptTypes = &This->m_mt; + This->pSource->pPin->pin.cAcceptTypes = 1; + return NOERROR; err:; return hr; @@ -544,6 +806,8 @@ static HRESULT CAsyncSourcePinImpl_OnPreConnect( CPinBaseImpl* pImpl, IPin* pPin { CAsyncSourcePinImpl_THIS(pImpl,pin); + TRACE("(%p,%p)\n",This,pPin); + This->bAsyncReaderQueried = FALSE; return NOERROR; @@ -553,6 +817,8 @@ static HRESULT CAsyncSourcePinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPi { CAsyncSourcePinImpl_THIS(pImpl,pin); + TRACE("(%p,%p)\n",This,pPin); + if ( !This->bAsyncReaderQueried ) return E_FAIL; @@ -563,6 +829,8 @@ static HRESULT CAsyncSourcePinImpl_OnDisconnect( CPinBaseImpl* pImpl ) { CAsyncSourcePinImpl_THIS(pImpl,pin); + TRACE("(%p)\n",This); + This->bAsyncReaderQueried = FALSE; return NOERROR; @@ -723,7 +991,14 @@ HRESULT QUARTZ_CreateAsyncSource( InitializeCriticalSection( &This->csFilter ); /* create the output pin. */ - hr = S_OK; + hr = QUARTZ_CreateAsyncSourcePin( + This, &This->csFilter, + &This->pPin, pwszOutPinName ); + if ( SUCCEEDED(hr) ) + hr = QUARTZ_CompList_AddComp( + This->basefilter.pOutPins, + (IUnknown*)&(This->pPin->pin), + NULL, 0 ); if ( FAILED(hr) ) { @@ -756,6 +1031,7 @@ static HRESULT CAsyncSourceImpl_OnQueryInterface( if ( IsEqualGUID( &IID_IAsyncReader, piid ) ) { + TRACE("IAsyncReader has been queried.\n"); *ppobj = (void*)&This->async; IUnknown_AddRef(punk); This->bAsyncReaderQueried = TRUE; @@ -813,8 +1089,7 @@ HRESULT QUARTZ_CreateAsyncSourcePin( hr = CAsyncReaderImpl_InitIAsyncReader( &This->async, This->unk.punkControl, - pFilter, - pcsPin ); + pFilter ); if ( FAILED(hr) ) { CPinBaseImpl_UninitIPin( &This->pin ); @@ -838,3 +1113,231 @@ HRESULT QUARTZ_CreateAsyncSourcePin( return S_OK; } + + +/*************************************************************************** + * + * Implements File Source. + * + */ + +typedef struct AsyncSourceFileImpl +{ + HANDLE hFile; + LONGLONG llTotal; +} AsyncSourceFileImpl; + + +static HRESULT AsyncSourceFileImpl_Load( CAsyncSourceImpl* pImpl, LPCWSTR lpwszSourceName ) +{ + AsyncSourceFileImpl* This = (AsyncSourceFileImpl*)pImpl->m_pUserData; + DWORD dwLow; + DWORD dwHigh; + + if ( This != NULL ) + return E_UNEXPECTED; + This = (AsyncSourceFileImpl*)QUARTZ_AllocMem( sizeof(AsyncSourceFileImpl) ); + pImpl->m_pUserData = (void*)This; + if ( This == NULL ) + return E_OUTOFMEMORY; + This->hFile = INVALID_HANDLE_VALUE; + This->llTotal = 0; + + This->hFile = CreateFileW( lpwszSourceName, + GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL ); + if ( This->hFile == INVALID_HANDLE_VALUE ) + return E_FAIL; + + SetLastError(NO_ERROR); + dwLow = GetFileSize( This->hFile, &dwHigh ); + if ( dwLow == 0xffffffff && GetLastError() != NO_ERROR ) + return E_FAIL; + + This->llTotal = (LONGLONG)dwLow | ((LONGLONG)dwHigh << 32); + + return NOERROR; +} + +static HRESULT AsyncSourceFileImpl_Cleanup( CAsyncSourceImpl* pImpl ) +{ + AsyncSourceFileImpl* This = (AsyncSourceFileImpl*)pImpl->m_pUserData; + + if ( This == NULL ) + return NOERROR; + + if ( This->hFile != INVALID_HANDLE_VALUE ) + CloseHandle(This->hFile); + + QUARTZ_FreeMem(This); + pImpl->m_pUserData = NULL; + + return NOERROR; +} + +static HRESULT AsyncSourceFileImpl_GetLength( CAsyncSourceImpl* pImpl, LONGLONG* pllTotal, LONGLONG* pllAvailable ) +{ + AsyncSourceFileImpl* This = (AsyncSourceFileImpl*)pImpl->m_pUserData; + + if ( This == NULL ) + return E_UNEXPECTED; + + *pllTotal = This->llTotal; + *pllAvailable = This->llTotal; + + return NOERROR; +} + +static HRESULT AsyncSourceFileImpl_Read( CAsyncSourceImpl* pImpl, LONGLONG llOfsStart, LONG lLength, BYTE* pBuf, LONG* plReturned, HANDLE hEventCancel ) +{ + AsyncSourceFileImpl* This = (AsyncSourceFileImpl*)pImpl->m_pUserData; + LONG lReturned; + LONG lBlock; + LONG lOfsLow; + LONG lOfsHigh; + DWORD dw; + HRESULT hr = S_OK; + + if ( This == NULL || This->hFile == INVALID_HANDLE_VALUE ) + return E_UNEXPECTED; + + lReturned = 0; + + lOfsLow = (LONG)(llOfsStart & 0xffffffff); + lOfsHigh = (LONG)(llOfsStart >> 32); + SetLastError(NO_ERROR); + lOfsLow = SetFilePointer( This->hFile, lOfsLow, &lOfsHigh, FILE_BEGIN ); + if ( lOfsLow == (LONG)0xffffffff && GetLastError() != NO_ERROR ) + return E_FAIL; + + while ( lLength > 0 ) + { + if ( WaitForSingleObject( hEventCancel, 0 ) == WAIT_OBJECT_0 ) + { + hr = S_FALSE; + break; + } + + lBlock = ( lLength > ASYNCSRC_FILE_BLOCKSIZE ) ? + ASYNCSRC_FILE_BLOCKSIZE : lLength; + + if ( !ReadFile(This->hFile,pBuf,(DWORD)lBlock,&dw,NULL) ) + { + hr = E_FAIL; + break; + } + pBuf += dw; + lReturned += (LONG)dw; + lLength -= (LONG)dw; + if ( lBlock > (LONG)dw ) + break; + } + + *plReturned = lReturned; + + return hr; +} + +static const struct AsyncSourceHandlers asyncsrc_file = +{ + AsyncSourceFileImpl_Load, + AsyncSourceFileImpl_Cleanup, + AsyncSourceFileImpl_GetLength, + AsyncSourceFileImpl_Read, +}; + +HRESULT QUARTZ_CreateAsyncReader(IUnknown* punkOuter,void** ppobj) +{ + return QUARTZ_CreateAsyncSource( + punkOuter, ppobj, + &CLSID_AsyncReader, + QUARTZ_wszAsyncFileSourceName, + QUARTZ_wszAsyncFileSourcePinName, + &asyncsrc_file ); +} + +/*************************************************************************** + * + * Implements URL Source. + * + */ + +typedef struct AsyncSourceURLImpl +{ + DWORD dwDummy; +} AsyncSourceURLImpl; + + +static HRESULT AsyncSourceURLImpl_Load( CAsyncSourceImpl* pImpl, LPCWSTR lpwszSourceName ) +{ + AsyncSourceURLImpl* This = (AsyncSourceURLImpl*)pImpl->m_pUserData; + + FIXME("(%p,%p) stub!\n", pImpl, lpwszSourceName); + + if ( This != NULL ) + return E_UNEXPECTED; + This = (AsyncSourceURLImpl*)QUARTZ_AllocMem( sizeof(AsyncSourceURLImpl) ); + pImpl->m_pUserData = (void*)This; + if ( This == NULL ) + return E_OUTOFMEMORY; + + return E_NOTIMPL; +} + +static HRESULT AsyncSourceURLImpl_Cleanup( CAsyncSourceImpl* pImpl ) +{ + AsyncSourceURLImpl* This = (AsyncSourceURLImpl*)pImpl->m_pUserData; + + FIXME("(%p) stub!\n", This); + + if ( This == NULL ) + return NOERROR; + + QUARTZ_FreeMem(This); + pImpl->m_pUserData = NULL; + + return NOERROR; +} + +static HRESULT AsyncSourceURLImpl_GetLength( CAsyncSourceImpl* pImpl, LONGLONG* pllTotal, LONGLONG* pllAvailable ) +{ + AsyncSourceURLImpl* This = (AsyncSourceURLImpl*)pImpl->m_pUserData; + + FIXME("(%p,%p,%p) stub!\n", This, pllTotal, pllAvailable); + + if ( This == NULL ) + return E_UNEXPECTED; + + return E_NOTIMPL; +} + +static HRESULT AsyncSourceURLImpl_Read( CAsyncSourceImpl* pImpl, LONGLONG llOfsStart, LONG lLength, BYTE* pBuf, LONG* plReturned, HANDLE hEventCancel ) +{ + AsyncSourceURLImpl* This = (AsyncSourceURLImpl*)pImpl->m_pUserData; + + FIXME("(%p) stub!\n", This); + + if ( This == NULL ) + return E_UNEXPECTED; + + return E_NOTIMPL; +} + +static const struct AsyncSourceHandlers asyncsrc_url = +{ + AsyncSourceURLImpl_Load, + AsyncSourceURLImpl_Cleanup, + AsyncSourceURLImpl_GetLength, + AsyncSourceURLImpl_Read, +}; + + +HRESULT QUARTZ_CreateURLReader(IUnknown* punkOuter,void** ppobj) +{ + return QUARTZ_CreateAsyncSource( + punkOuter, ppobj, + &CLSID_URLReader, + QUARTZ_wszAsyncURLSourceName, + QUARTZ_wszAsyncURLSourcePinName, + &asyncsrc_url ); +} diff --git a/dlls/quartz/asyncsrc.h b/dlls/quartz/asyncsrc.h index 57e769d5ffe..ec1b6e2f8aa 100644 --- a/dlls/quartz/asyncsrc.h +++ b/dlls/quartz/asyncsrc.h @@ -12,6 +12,7 @@ typedef struct CAsyncSourceImpl CAsyncSourceImpl; typedef struct CAsyncSourcePinImpl CAsyncSourcePinImpl; +typedef struct AsyncSourceRequest AsyncSourceRequest; typedef struct AsyncSourceHandlers AsyncSourceHandlers; typedef struct CAsyncReaderImpl @@ -23,13 +24,20 @@ typedef struct CAsyncReaderImpl /* IAsyncReader fields */ CAsyncSourceImpl* pSource; - CRITICAL_SECTION* pcsReader; + CRITICAL_SECTION m_csReader; + BOOL m_bInFlushing; + BOOL m_bAbortThread; HANDLE m_hEventInit; - HANDLE m_hEventAbort; + HANDLE m_hEventCancel; HANDLE m_hEventReqQueued; HANDLE m_hEventSampQueued; - HANDLE m_hEventCompletion; HANDLE m_hThread; + CRITICAL_SECTION m_csRequest; + AsyncSourceRequest* m_pRequestFirst; + CRITICAL_SECTION m_csReply; + AsyncSourceRequest* m_pReplyFirst; + CRITICAL_SECTION m_csFree; + AsyncSourceRequest* m_pFreeFirst; } CAsyncReaderImpl; typedef struct CFileSourceFilterImpl @@ -70,15 +78,27 @@ struct CAsyncSourcePinImpl CAsyncSourceImpl* pSource; }; +struct AsyncSourceRequest +{ + AsyncSourceRequest* pNext; + + LONGLONG llStart; + LONG lLength; + LONG lActual; + BYTE* pBuf; + IMediaSample* pSample; /* for async req. */ + DWORD_PTR dwContext; /* for async req. */ +}; + struct AsyncSourceHandlers { /* all handlers MUST be implemented. */ HRESULT (*pLoad)( CAsyncSourceImpl* pImpl, LPCWSTR lpwszSourceName ); HRESULT (*pCleanup)( CAsyncSourceImpl* pImpl ); HRESULT (*pGetLength)( CAsyncSourceImpl* pImpl, LONGLONG* pllTotal, LONGLONG* pllAvailable ); - HRESULT (*pReadAsync)( CAsyncSourceImpl* pImpl, LONGLONG llOfsStart, LONG lLength, BYTE* pBuf, HANDLE hEventCompletion ); - HRESULT (*pGetResult)( CAsyncSourceImpl* pImpl, LONG* plReturned ); - HRESULT (*pCancelAsync)( CAsyncSourceImpl* pImpl ); + /* S_OK = OK / S_FALSE = Canceled / other = error */ + /* hEventCancel may be NULL */ + HRESULT (*pRead)( CAsyncSourceImpl* pImpl, LONGLONG llOfsStart, LONG lLength, BYTE* pBuf, LONG* plReturned, HANDLE hEventCancel ); }; #define CAsyncSourceImpl_THIS(iface,member) CAsyncSourceImpl* This = ((CAsyncSourceImpl*)(((char*)iface)-offsetof(CAsyncSourceImpl,member))) @@ -87,8 +107,7 @@ struct AsyncSourceHandlers HRESULT CAsyncReaderImpl_InitIAsyncReader( CAsyncReaderImpl* This, IUnknown* punkControl, - CAsyncSourceImpl* pSource, - CRITICAL_SECTION* pcsReader ); + CAsyncSourceImpl* pSource ); void CAsyncReaderImpl_UninitIAsyncReader( CAsyncReaderImpl* This ); HRESULT CFileSourceFilterImpl_InitIFileSourceFilter( @@ -112,4 +131,10 @@ HRESULT QUARTZ_CreateAsyncSourcePin( LPCWSTR pwszPinName ); +HRESULT QUARTZ_CreateAsyncReader(IUnknown* punkOuter,void** ppobj); +HRESULT QUARTZ_CreateURLReader(IUnknown* punkOuter,void** ppobj); + +#define ASYNCSRC_FILE_BLOCKSIZE 4096 + + #endif /* WINE_DSHOW_ASYNCSRC_H */ diff --git a/dlls/quartz/audioutl.c b/dlls/quartz/audioutl.c new file mode 100644 index 00000000000..a9ef997b9f9 --- /dev/null +++ b/dlls/quartz/audioutl.c @@ -0,0 +1,63 @@ +/* + * hidenori@a2.ctktv.ne.jp + */ + +#include "config.h" + +#include "windef.h" + +#include "debugtools.h" +DEFAULT_DEBUG_CHANNEL(quartz); + +#include "audioutl.h" + + +void AUDIOUTL_ChangeSign8( BYTE* pbData, DWORD cbData ) +{ + BYTE* pbEnd = pbData + cbData; + + while ( pbData < pbEnd ) + { + *pbData ^= 0x80; + pbData ++; + } +} + +void AUDIOUTL_ChangeSign16LE( BYTE* pbData, DWORD cbData ) +{ + BYTE* pbEnd = pbData + cbData; + + pbData ++; + while ( pbData < pbEnd ) + { + *pbData ^= 0x80; + pbData += 2; + } +} + +void AUDIOUTL_ChangeSign16BE( BYTE* pbData, DWORD cbData ) +{ + BYTE* pbEnd = pbData + cbData; + + while ( pbData < pbEnd ) + { + *pbData ^= 0x80; + pbData += 2; + } +} + +void AUDIOUTL_ByteSwap( BYTE* pbData, DWORD cbData ) +{ + BYTE* pbEnd = pbData + cbData - 1; + BYTE bTemp; + + while ( pbData < pbEnd ) + { + bTemp = pbData[0]; + pbData[0] = pbData[1]; + pbData[1] = bTemp; + pbData += 2; + } +} + + diff --git a/dlls/quartz/audioutl.h b/dlls/quartz/audioutl.h new file mode 100644 index 00000000000..fcb8beb3607 --- /dev/null +++ b/dlls/quartz/audioutl.h @@ -0,0 +1,11 @@ +#ifndef QUARTZ_AUDIOUTL_H +#define QUARTZ_AUDIOUTL_H + + +void AUDIOUTL_ChangeSign8( BYTE* pbData, DWORD cbData ); +void AUDIOUTL_ChangeSign16LE( BYTE* pbData, DWORD cbData ); +void AUDIOUTL_ChangeSign16BE( BYTE* pbData, DWORD cbData ); +void AUDIOUTL_ByteSwap( BYTE* pbData, DWORD cbData ); + + +#endif /* QUARTZ_AUDIOUTL_H */ diff --git a/dlls/quartz/audren.c b/dlls/quartz/audren.c index 50e613ea5b3..92dc9615abc 100644 --- a/dlls/quartz/audren.c +++ b/dlls/quartz/audren.c @@ -16,8 +16,6 @@ #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" diff --git a/dlls/quartz/aviparse.c b/dlls/quartz/aviparse.c new file mode 100644 index 00000000000..6e94c4d28d4 --- /dev/null +++ b/dlls/quartz/aviparse.c @@ -0,0 +1,695 @@ +/* + * Implements AVI Parser(Splitter). + * + * hidenori@a2.ctktv.ne.jp + */ + +#include "config.h" + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "mmsystem.h" +#include "vfw.h" +#include "winerror.h" +#include "strmif.h" +#include "vfwmsgs.h" +#include "amvideo.h" +#include "uuids.h" + +#include "debugtools.h" +DEFAULT_DEBUG_CHANNEL(quartz); + +#include "quartz_private.h" +#include "parser.h" +#include "mtype.h" + + + +static const WCHAR QUARTZ_AVIParser_Name[] = +{ 'A','V','I',' ','S','p','l','i','t','t','e','r',0 }; +static const WCHAR QUARTZ_AVIParserInPin_Name[] = +{ 'I','n',0 }; +static const WCHAR QUARTZ_AVIParserOutPin_Basename[] = +{ 'S','t','r','e','a','m',0 }; + +#define WINE_QUARTZ_AVIPINNAME_MAX 64 + +/**************************************************************************** + * + * CAVIParseImpl + */ + + +typedef struct CAVIParseImpl CAVIParseImpl; +typedef struct CAVIParseStream CAVIParseStream; + +struct CAVIParseImpl +{ + MainAVIHeader avih; + CAVIParseStream* pStreamsBuf; + DWORD cIndexEntries; + AVIINDEXENTRY* pIndexEntriesBuf; + WCHAR wchWork[ WINE_QUARTZ_AVIPINNAME_MAX ]; +}; + +struct CAVIParseStream +{ + AVIStreamHeader strh; + DWORD cbFmt; + BYTE* pFmtBuf; + DWORD cIndexEntries; + AVIINDEXENTRY* pIndexEntries; + DWORD cIndexCur; + REFERENCE_TIME rtCur; + REFERENCE_TIME rtInternal; +}; + + +static HRESULT CAVIParseImpl_ParseStreamList( + CParserImpl* pImpl, CAVIParseImpl* This, ULONG nStreamIndex, + LONGLONG llOfsTop, DWORD dwListLen, CAVIParseStream* pStream ) +{ + HRESULT hr; + LONGLONG llOfs; + DWORD dwChunkLength; + + TRACE("search strh\n"); + hr = RIFF_SearchChunk( + pImpl, dwListLen, + llOfsTop, PARSER_strh, + &llOfs, &dwChunkLength ); + if ( hr == S_OK ) + { + TRACE("strh has been detected\n"); + if ( dwChunkLength < sizeof(AVIStreamHeader) ) + hr = E_FAIL; + else + hr = IAsyncReader_SyncRead( pImpl->m_pReader, + llOfs, sizeof(AVIStreamHeader), (BYTE*)&pStream->strh ); + } + if ( FAILED(hr) ) + return hr; + if ( hr != S_OK ) + return E_FAIL; + + TRACE("search strf\n"); + hr = RIFF_SearchChunk( + pImpl, dwListLen, + llOfsTop, PARSER_strf, + &llOfs, &dwChunkLength ); + if ( hr == S_OK && dwChunkLength > 0 ) + { + TRACE("strf has been detected\n"); + pStream->cbFmt = dwChunkLength; + pStream->pFmtBuf = (BYTE*)QUARTZ_AllocMem( dwChunkLength ); + if ( pStream->pFmtBuf == NULL ) + hr = E_OUTOFMEMORY; + else + hr = IAsyncReader_SyncRead( pImpl->m_pReader, + llOfs, dwChunkLength, pStream->pFmtBuf ); + } + if ( FAILED(hr) ) + return hr; + + TRACE("search indx\n"); + hr = RIFF_SearchChunk( + pImpl, dwListLen, + llOfsTop, PARSER_indx, + &llOfs, &dwChunkLength ); + if ( FAILED(hr) ) + return hr; + if ( hr == S_OK ) + { + FIXME( "'indx' has been detected - not implemented now!\n" ); + return E_FAIL; + } + + return NOERROR; +} + + +static HRESULT CAVIParseImpl_InitParser( CParserImpl* pImpl, ULONG* pcStreams ) +{ + CAVIParseImpl* This = NULL; + BYTE riffhdr[12]; + ULONG i; + ULONG nIndex; + HRESULT hr; + LONGLONG llOfs_hdrl; + DWORD dwLen_hdrl; + LONGLONG llOfs; + DWORD dwChunkId; + DWORD dwChunkLength; + AVIINDEXENTRY* pEntriesBuf = NULL; + ULONG cEntries; + ULONG cEntriesCur; + + TRACE("(%p,%p)\n",pImpl,pcStreams); + + hr = IAsyncReader_SyncRead( pImpl->m_pReader, 0, 12, riffhdr ); + if ( FAILED(hr) ) + return hr; + if ( hr != S_OK ) + return E_FAIL; + if ( memcmp( &riffhdr[0], "RIFF", 4 ) != 0 || + memcmp( &riffhdr[8], "AVI ", 4 ) != 0 ) + return E_FAIL; + + TRACE("it's AVI\n"); + + This = (CAVIParseImpl*)QUARTZ_AllocMem( sizeof(CAVIParseImpl) ); + if ( This == NULL ) + return E_OUTOFMEMORY; + pImpl->m_pUserData = This; + ZeroMemory( This, sizeof(CAVIParseImpl) ); + This->pStreamsBuf = NULL; + This->cIndexEntries = 0; + This->pIndexEntriesBuf = 0; + + hr = RIFF_SearchList( + pImpl, (DWORD)0xffffffff, + PARSER_RIFF_OfsFirst, PARSER_hdrl, + &llOfs_hdrl, &dwLen_hdrl ); + if ( FAILED(hr) ) + return hr; + if ( hr != S_OK ) + return E_FAIL; + + /* read 'avih' */ + TRACE("read avih\n"); + hr = RIFF_SearchChunk( + pImpl, dwLen_hdrl, + llOfs_hdrl, PARSER_avih, + &llOfs, &dwChunkLength ); + if ( FAILED(hr) ) + return hr; + if ( hr != S_OK ) + return E_FAIL; + + if ( dwChunkLength > sizeof(MainAVIHeader) ) + dwChunkLength = sizeof(MainAVIHeader); + hr = IAsyncReader_SyncRead( pImpl->m_pReader, llOfs, dwChunkLength, (BYTE*)&(This->avih) ); + if ( FAILED(hr) ) + return hr; + if ( hr != S_OK ) + return E_FAIL; + if ( This->avih.dwStreams == 0 ) + return E_FAIL; + + /* initialize streams. */ + This->pStreamsBuf = (CAVIParseStream*)QUARTZ_AllocMem( + sizeof(CAVIParseStream) * This->avih.dwStreams ); + if ( This->pStreamsBuf == NULL ) + return E_OUTOFMEMORY; + ZeroMemory( This->pStreamsBuf, + sizeof(CAVIParseStream) * This->avih.dwStreams ); + + llOfs = llOfs_hdrl; + for ( nIndex = 0; nIndex < This->avih.dwStreams; nIndex++ ) + { + TRACE("search strl for stream %lu\n",nIndex); + hr = RIFF_SearchList( + pImpl, + dwLen_hdrl, llOfs, PARSER_strl, + &llOfs, &dwChunkLength ); + if ( FAILED(hr) ) + return hr; + if ( hr != S_OK ) + return E_FAIL; + + /* read 'strl'. */ + hr = CAVIParseImpl_ParseStreamList( + pImpl, This, nIndex, + llOfs, dwChunkLength, &This->pStreamsBuf[nIndex] ); + + if ( FAILED(hr) ) + return hr; + if ( hr != S_OK ) + return E_FAIL; + llOfs += dwChunkLength; + } + + /* initialize idx1. */ + TRACE("search idx1\n"); + hr = RIFF_SearchChunk( + pImpl, (DWORD)0xffffffff, + PARSER_RIFF_OfsFirst, PARSER_idx1, + &llOfs, &dwChunkLength ); + if ( FAILED(hr) ) + return hr; + if ( hr == S_OK ) + { + /* read idx1. */ + This->cIndexEntries = dwChunkLength / sizeof(AVIINDEXENTRY); + This->pIndexEntriesBuf = (AVIINDEXENTRY*)QUARTZ_AllocMem( + sizeof(AVIINDEXENTRY) * This->cIndexEntries ); + if ( This->pIndexEntriesBuf == NULL ) + return E_OUTOFMEMORY; + hr = IAsyncReader_SyncRead( pImpl->m_pReader, llOfs, sizeof(AVIINDEXENTRY) * This->cIndexEntries, (BYTE*)This->pIndexEntriesBuf ); + if ( FAILED(hr) ) + return hr; + if ( hr != S_OK ) + return E_FAIL; + + pEntriesBuf = (AVIINDEXENTRY*)QUARTZ_AllocMem( + sizeof(AVIINDEXENTRY) * This->cIndexEntries ); + if ( pEntriesBuf == NULL ) + return E_OUTOFMEMORY; + cEntries = 0; + for ( nIndex = 0; nIndex < This->avih.dwStreams; nIndex++ ) + { + cEntriesCur = cEntries; + dwChunkId = (((nIndex%10)+'0')<<8) | ((nIndex/10)+'0'); + for ( i = 0; i < This->cIndexEntries; i++ ) + { + if ( (This->pIndexEntriesBuf[i].ckid & 0xffff) == dwChunkId ) + memcpy( &pEntriesBuf[cEntries++], &This->pIndexEntriesBuf[i], sizeof(AVIINDEXENTRY) ); + } + This->pStreamsBuf[nIndex].pIndexEntries = &pEntriesBuf[cEntriesCur]; + This->pStreamsBuf[nIndex].cIndexEntries = cEntries - cEntriesCur; + This->pStreamsBuf[nIndex].cIndexCur = 0; + This->pStreamsBuf[nIndex].rtCur = 0; + This->pStreamsBuf[nIndex].rtInternal = 0; + TRACE("stream %lu - %lu entries\n",nIndex,This->pStreamsBuf[nIndex].cIndexEntries); + } + QUARTZ_FreeMem(This->pIndexEntriesBuf); + This->pIndexEntriesBuf = pEntriesBuf; + + This->avih.dwSuggestedBufferSize = 0; + for ( i = 0; i < This->cIndexEntries; i++ ) + { + if ( This->avih.dwSuggestedBufferSize < This->pIndexEntriesBuf[i].dwChunkLength ) + This->avih.dwSuggestedBufferSize = This->pIndexEntriesBuf[i].dwChunkLength; + } + } + else + { + return E_FAIL; + } + + if ( This->avih.dwStreams > 100 ) + return E_FAIL; + + *pcStreams = This->avih.dwStreams; + + return NOERROR; +} + +static HRESULT CAVIParseImpl_UninitParser( CParserImpl* pImpl ) +{ + CAVIParseImpl* This = (CAVIParseImpl*)pImpl->m_pUserData; + ULONG nIndex; + + TRACE("(%p)\n",This); + + if ( This == NULL ) + return NOERROR; + + /* destruct */ + if ( This->pStreamsBuf != NULL ) + { + for ( nIndex = 0; nIndex < This->avih.dwStreams; nIndex++ ) + { + /* release this stream */ + if ( This->pStreamsBuf[nIndex].pFmtBuf != NULL ) + QUARTZ_FreeMem(This->pStreamsBuf[nIndex].pFmtBuf); + } + QUARTZ_FreeMem( This->pStreamsBuf ); + This->pStreamsBuf = NULL; + } + + if ( This->pIndexEntriesBuf != NULL ) + { + QUARTZ_FreeMem( This->pIndexEntriesBuf ); + This->pIndexEntriesBuf = NULL; + } + + QUARTZ_FreeMem( This ); + pImpl->m_pUserData = NULL; + + return NOERROR; +} + +static LPCWSTR CAVIParseImpl_GetOutPinName( CParserImpl* pImpl, ULONG nStreamIndex ) +{ + CAVIParseImpl* This = (CAVIParseImpl*)pImpl->m_pUserData; + int wlen; + + TRACE("(%p,%lu)\n",This,nStreamIndex); + + if ( This == NULL || nStreamIndex >= This->avih.dwStreams ) + return NULL; + + wlen = lstrlenW(QUARTZ_AVIParserOutPin_Basename); + memcpy( This->wchWork, QUARTZ_AVIParserOutPin_Basename, sizeof(WCHAR)*wlen ); + This->wchWork[ wlen ] = (nStreamIndex/10) + '0'; + This->wchWork[ wlen+1 ] = (nStreamIndex%10) + '0'; + This->wchWork[ wlen+2 ] = 0; + + return This->wchWork; +} + +static HRESULT CAVIParseImpl_GetStreamType( CParserImpl* pImpl, ULONG nStreamIndex, AM_MEDIA_TYPE* pmt ) +{ + CAVIParseImpl* This = (CAVIParseImpl*)pImpl->m_pUserData; + VIDEOINFOHEADER* pvi; + BITMAPINFOHEADER* pbi; + WAVEFORMATEX* pwfx; + DWORD cbFmt; + DWORD cb; + HRESULT hr; + + TRACE("(%p,%lu,%p)\n",This,nStreamIndex,pmt); + + if ( This == NULL ) + return E_UNEXPECTED; + if ( nStreamIndex >= This->avih.dwStreams ) + return E_INVALIDARG; + + cbFmt = This->pStreamsBuf[nStreamIndex].cbFmt; + + ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) ); + switch ( This->pStreamsBuf[nStreamIndex].strh.fccType ) + { + case PARSER_vids: + pbi = (BITMAPINFOHEADER*)This->pStreamsBuf[nStreamIndex].pFmtBuf; + if ( pbi == NULL || cbFmt < sizeof(BITMAPINFOHEADER) ) + goto unknown_format; + + memcpy( &pmt->majortype, &MEDIATYPE_Video, sizeof(GUID) ); + hr = QUARTZ_MediaSubType_FromBitmap( &pmt->subtype, pbi ); + if ( FAILED(hr) ) + goto unknown_format; + if ( hr != S_OK ) + QUARTZ_MediaSubType_FromFourCC( &pmt->subtype, (DWORD)pbi->biCompression ); + + pmt->bFixedSizeSamples = ( pbi->biCompression == 0 || pbi->biCompression == 3 ) ? 1 : 0; + pmt->bTemporalCompression = 0; + pmt->lSampleSize = ( pbi->biCompression == 0 || pbi->biCompression == 3 ) ? + DIBSIZE(*pbi) : pbi->biSize; + memcpy( &pmt->formattype, &FORMAT_VideoInfo, sizeof(GUID) ); + + cb = sizeof(VIDEOINFOHEADER) + cbFmt; + pmt->pbFormat = (BYTE*)CoTaskMemAlloc( cb ); + if ( pmt->pbFormat == NULL ) + return E_OUTOFMEMORY; + ZeroMemory( pmt->pbFormat, cb ); + pvi = (VIDEOINFOHEADER*)pmt->pbFormat; + pmt->cbFormat = cb; + memcpy( &pvi->bmiHeader, pbi, cbFmt ); + break; + case PARSER_auds: + pwfx = (WAVEFORMATEX*)This->pStreamsBuf[nStreamIndex].pFmtBuf; + if ( pwfx == NULL || cbFmt < (sizeof(WAVEFORMATEX)-2) ) + goto unknown_format; + + memcpy( &pmt->majortype, &MEDIATYPE_Audio, sizeof(GUID) ); + QUARTZ_MediaSubType_FromFourCC( &pmt->subtype, (DWORD)pwfx->wFormatTag ); + pmt->bFixedSizeSamples = 1; + pmt->bTemporalCompression = 0; + pmt->lSampleSize = pwfx->nBlockAlign; + memcpy( &pmt->formattype, &FORMAT_WaveFormatEx, sizeof(GUID) ); + pmt->pUnk = NULL; + + cb = ( cbFmt < sizeof(WAVEFORMATEX) ) ? sizeof(WAVEFORMATEX) : cbFmt; + pmt->pbFormat = (BYTE*)CoTaskMemAlloc( cb ); + if ( pmt->pbFormat == NULL ) + return E_OUTOFMEMORY; + ZeroMemory( pmt->pbFormat, cb ); + pmt->cbFormat = cbFmt; + memcpy( pmt->pbFormat, pwfx, cbFmt ); + break; + case PARSER_mids: + /* FIXME? */ + memcpy( &pmt->majortype, &MEDIATYPE_Midi, sizeof(GUID) ); + memcpy( &pmt->subtype, &MEDIASUBTYPE_NULL, sizeof(GUID) ); + pmt->bFixedSizeSamples = 0; + pmt->bTemporalCompression = 0; + pmt->lSampleSize = 1; + memcpy( &pmt->formattype, &FORMAT_None, sizeof(GUID) ); + pmt->pUnk = NULL; + pmt->cbFormat = 0; + pmt->pbFormat = NULL; + break; + case PARSER_txts: + /* FIXME? */ + memcpy( &pmt->majortype, &MEDIATYPE_Text, sizeof(GUID) ); + memcpy( &pmt->subtype, &MEDIASUBTYPE_NULL, sizeof(GUID) ); + pmt->bFixedSizeSamples = 0; + pmt->bTemporalCompression = 0; + pmt->lSampleSize = 1; + memcpy( &pmt->formattype, &FORMAT_None, sizeof(GUID) ); + pmt->pUnk = NULL; + pmt->cbFormat = 0; + pmt->pbFormat = NULL; + break; + default: + goto unknown_format; + } + + return NOERROR; + +unknown_format:; + FIXME( "(%p) unsupported stream type %c%c%c%c\n",This, + (int)((This->pStreamsBuf[nStreamIndex].strh.fccType>> 0)&0xff), + (int)((This->pStreamsBuf[nStreamIndex].strh.fccType>> 8)&0xff), + (int)((This->pStreamsBuf[nStreamIndex].strh.fccType>>16)&0xff), + (int)((This->pStreamsBuf[nStreamIndex].strh.fccType>>24)&0xff) ); + + memcpy( &pmt->majortype, &MEDIATYPE_NULL, sizeof(GUID) ); + memcpy( &pmt->subtype, &MEDIASUBTYPE_NULL, sizeof(GUID) ); + pmt->bFixedSizeSamples = 0; + pmt->bTemporalCompression = 0; + pmt->lSampleSize = 1; + memcpy( &pmt->formattype, &FORMAT_None, sizeof(GUID) ); + pmt->pUnk = NULL; + pmt->cbFormat = 0; + pmt->pbFormat = NULL; + + return NOERROR; +} + +static HRESULT CAVIParseImpl_CheckStreamType( CParserImpl* pImpl, ULONG nStreamIndex, const AM_MEDIA_TYPE* pmt ) +{ + CAVIParseImpl* This = (CAVIParseImpl*)pImpl->m_pUserData; + HRESULT hr; + AM_MEDIA_TYPE mt; + VIDEOINFOHEADER* pvi; + VIDEOINFOHEADER* pviCheck; + WAVEFORMATEX* pwfx; + WAVEFORMATEX* pwfxCheck; + + TRACE("(%p,%lu,%p)\n",This,nStreamIndex,pmt); + + hr = CAVIParseImpl_GetStreamType( pImpl, nStreamIndex, &mt ); + if ( FAILED(hr) ) + return hr; + + TRACE("check GUIDs - %s,%s\n",debugstr_guid(&pmt->majortype),debugstr_guid(&pmt->subtype)); + if ( !IsEqualGUID( &pmt->majortype, &mt.majortype ) || + !IsEqualGUID( &pmt->subtype, &mt.subtype ) || + !IsEqualGUID( &pmt->formattype, &mt.formattype ) ) + { + hr = E_FAIL; + goto end; + } + + TRACE("check format\n"); + hr = S_OK; + switch ( This->pStreamsBuf[nStreamIndex].strh.fccType ) + { + case PARSER_vids: + TRACE("check vids\n"); + pvi = (VIDEOINFOHEADER*)mt.pbFormat; + pviCheck = (VIDEOINFOHEADER*)pmt->pbFormat; + if ( pvi == NULL || pviCheck == NULL || pmt->cbFormat < sizeof(VIDEOINFOHEADER) ) + hr = E_FAIL; + if ( pvi->bmiHeader.biWidth != pviCheck->bmiHeader.biWidth || + pvi->bmiHeader.biHeight != pviCheck->bmiHeader.biHeight || + pvi->bmiHeader.biPlanes != pviCheck->bmiHeader.biPlanes || + pvi->bmiHeader.biBitCount != pviCheck->bmiHeader.biBitCount || + pvi->bmiHeader.biCompression != pviCheck->bmiHeader.biCompression || + pvi->bmiHeader.biClrUsed != pviCheck->bmiHeader.biClrUsed ) + hr = E_FAIL; + break; + case PARSER_auds: + TRACE("check auds\n"); + pwfx = (WAVEFORMATEX*)mt.pbFormat; + pwfxCheck = (WAVEFORMATEX*)pmt->pbFormat; + if ( pwfx == NULL || pwfxCheck == NULL || pmt->cbFormat < (sizeof(WAVEFORMATEX)-2) ) + hr = E_FAIL; + if ( pwfx->wFormatTag != pwfxCheck->wFormatTag || + pwfx->nBlockAlign != pwfxCheck->nBlockAlign || + pwfx->wBitsPerSample != pwfxCheck->wBitsPerSample || + pwfx->nChannels != pwfxCheck->nChannels || + pwfx->nSamplesPerSec != pwfxCheck->nSamplesPerSec ) + hr = E_FAIL; + break; + case PARSER_mids: + case PARSER_txts: + break; + default: + break; + } +end: + QUARTZ_MediaType_Free( &mt ); + + TRACE("%08lx\n",hr); + + return hr; +} + +static HRESULT CAVIParseImpl_GetAllocProp( CParserImpl* pImpl, ALLOCATOR_PROPERTIES* pReqProp ) +{ + CAVIParseImpl* This = (CAVIParseImpl*)pImpl->m_pUserData; + + if ( This == NULL ) + return E_UNEXPECTED; + + ZeroMemory( pReqProp, sizeof(ALLOCATOR_PROPERTIES) ); + pReqProp->cBuffers = This->avih.dwStreams; + pReqProp->cbBuffer = This->avih.dwSuggestedBufferSize; + + return NOERROR; +} + +static HRESULT CAVIParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStreamIndex, LONGLONG* pllStart, LONG* plLength, REFERENCE_TIME* prtStart, REFERENCE_TIME* prtStop ) +{ + CAVIParseImpl* This = (CAVIParseImpl*)pImpl->m_pUserData; + REFERENCE_TIME rtNext; + DWORD nIndexNext; + DWORD nIndex; + CAVIParseStream* pStream; + const WAVEFORMATEX* pwfx; + + if ( This == NULL ) + return E_UNEXPECTED; + + TRACE("(%p)\n",This); + + nIndexNext = This->avih.dwStreams; + rtNext = ((REFERENCE_TIME)0x7fffffff<<32)|((REFERENCE_TIME)0xffffffff); + for ( nIndex = 0; nIndex < This->avih.dwStreams; nIndex++ ) + { + TRACE("stream %lu - %lu,%lu\n",nIndex,(unsigned long)(This->pStreamsBuf[nIndex].rtCur*1000/QUARTZ_TIMEUNITS),This->pStreamsBuf[nIndex].cIndexCur); + if ( rtNext > This->pStreamsBuf[nIndex].rtCur && + This->pStreamsBuf[nIndex].cIndexCur < This->pStreamsBuf[nIndex].cIndexEntries ) + { + nIndexNext = nIndex; + rtNext = This->pStreamsBuf[nIndex].rtCur; + } + } + if ( nIndexNext >= This->avih.dwStreams ) + return S_FALSE; + + if ( This->pIndexEntriesBuf != NULL ) + { + pStream = &This->pStreamsBuf[nIndexNext]; + *pnStreamIndex = nIndexNext; + *pllStart = (LONGLONG)pStream->pIndexEntries[pStream->cIndexCur].dwChunkOffset + 8; + *plLength = (LONG)pStream->pIndexEntries[pStream->cIndexCur].dwChunkLength; + *prtStart = rtNext; + *prtStop = rtNext; + + switch ( pStream->strh.fccType ) + { + case PARSER_vids: + TRACE("vids\n"); + pStream->rtInternal ++; + rtNext = pStream->rtInternal * (REFERENCE_TIME)QUARTZ_TIMEUNITS * (REFERENCE_TIME)pStream->strh.dwScale / (REFERENCE_TIME)pStream->strh.dwRate; + /* FIXME - handle AVIPALCHANGE */ + break; + case PARSER_auds: + TRACE("auds\n"); + pwfx = (const WAVEFORMATEX*)pStream->pFmtBuf; + if ( pwfx != NULL && pStream->cbFmt >= (sizeof(WAVEFORMATEX)-2) ) + { + pStream->rtInternal += (REFERENCE_TIME)*plLength; + rtNext = pStream->rtInternal * (REFERENCE_TIME)QUARTZ_TIMEUNITS / (REFERENCE_TIME)pwfx->nAvgBytesPerSec; + } + else + { + pStream->rtInternal += (REFERENCE_TIME)(*plLength); + rtNext = pStream->rtInternal * (REFERENCE_TIME)QUARTZ_TIMEUNITS * (REFERENCE_TIME)pStream->strh.dwScale / ((REFERENCE_TIME)pStream->strh.dwSampleSize * (REFERENCE_TIME)pStream->strh.dwRate); + } + break; + case PARSER_mids: + case PARSER_txts: + default: + pStream->rtInternal += (REFERENCE_TIME)(*plLength); + rtNext = pStream->rtInternal * (REFERENCE_TIME)QUARTZ_TIMEUNITS * (REFERENCE_TIME)pStream->strh.dwScale / ((REFERENCE_TIME)pStream->strh.dwSampleSize * (REFERENCE_TIME)pStream->strh.dwRate); + break; + } + pStream->cIndexCur ++; + pStream->rtCur = rtNext; + *prtStop = rtNext; + } + else + { + ERR( "no idx1\n" ); + return E_NOTIMPL; + } + + TRACE("return %lu / %ld-%ld / %lu-%lu\n", + *pnStreamIndex,(long)*pllStart,*plLength, + (unsigned long)((*prtStart)*1000/QUARTZ_TIMEUNITS), + (unsigned long)((*prtStop)*1000/QUARTZ_TIMEUNITS)); + + return NOERROR; +} + +static HRESULT CAVIParseImpl_ProcessSample( CParserImpl* pImpl, ULONG nStreamIndex, LONGLONG llStart, LONG lLength, IMediaSample* pSample ) +{ + CAVIParseImpl* This = (CAVIParseImpl*)pImpl->m_pUserData; + + TRACE("(%p,%lu,%ld,%ld,%p)\n",This,nStreamIndex,(long)llStart,lLength,pSample); + + if ( This == NULL ) + return E_UNEXPECTED; + + return NOERROR; +} + + + + +static const struct ParserHandlers CAVIParseImpl_Handlers = +{ + CAVIParseImpl_InitParser, + CAVIParseImpl_UninitParser, + CAVIParseImpl_GetOutPinName, + CAVIParseImpl_GetStreamType, + CAVIParseImpl_CheckStreamType, + CAVIParseImpl_GetAllocProp, + CAVIParseImpl_GetNextRequest, + CAVIParseImpl_ProcessSample, + + /* for IQualityControl */ + NULL, /* pQualityNotify */ + + /* for seeking */ + NULL, /* pGetSeekingCaps */ + NULL, /* pIsTimeFormatSupported */ + NULL, /* pGetCurPos */ + NULL, /* pSetCurPos */ + NULL, /* pGetDuration */ + NULL, /* pSetDuration */ + NULL, /* pGetStopPos */ + NULL, /* pSetStopPos */ + NULL, /* pGetPreroll */ + NULL, /* pSetPreroll */ +}; + +HRESULT QUARTZ_CreateAVISplitter(IUnknown* punkOuter,void** ppobj) +{ + return QUARTZ_CreateParser( + punkOuter,ppobj, + &CLSID_AviSplitter, + QUARTZ_AVIParser_Name, + QUARTZ_AVIParserInPin_Name, + &CAVIParseImpl_Handlers ); +} + + diff --git a/dlls/quartz/basefilt.c b/dlls/quartz/basefilt.c index c2db042325b..4bec553ad48 100644 --- a/dlls/quartz/basefilt.c +++ b/dlls/quartz/basefilt.c @@ -11,10 +11,8 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" #include "strmif.h" #include "vfwmsgs.h" -#include "wine/unicode.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); @@ -355,7 +353,7 @@ CBaseFilterImpl_fnJoinFilterGraph(IBaseFilter* iface,IFilterGraph* pfg,LPCWSTR l } This->pfg = pfg; - This->cbNameGraph = sizeof(WCHAR) * (strlenW(lpwszName)+1); + This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszName)+1); This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph ); if ( This->pwszNameGraph == NULL ) { @@ -440,7 +438,7 @@ HRESULT CBaseFilterImpl_InitIBaseFilter( This->rtStart = 0; This->fstate = State_Stopped; - This->cbNameGraph = sizeof(WCHAR) * (strlenW(lpwszNameGraph)+1); + This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszNameGraph)+1); This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph ); if ( This->pwszNameGraph == NULL ) return E_OUTOFMEMORY; diff --git a/dlls/quartz/basepin.c b/dlls/quartz/basepin.c index 1f809b7b3e3..ea414a69f8a 100644 --- a/dlls/quartz/basepin.c +++ b/dlls/quartz/basepin.c @@ -11,10 +11,8 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" #include "strmif.h" #include "vfwmsgs.h" -#include "wine/unicode.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); @@ -67,7 +65,7 @@ CPinBaseImpl_fnConnect(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt) HRESULT hr = E_NOTIMPL; ULONG i; - FIXME("(%p)->(%p,%p) stub!\n",This,pPin,pmt); + FIXME("(%p)->(%p,%p)\n",This,pPin,pmt); if ( !This->bOutput ) return E_UNEXPECTED; @@ -167,7 +165,7 @@ CPinBaseImpl_fnReceiveConnection(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt ICOM_THIS(CPinBaseImpl,iface); HRESULT hr = E_NOTIMPL; - FIXME("(%p)->(%p,%p) stub!\n",This,pPin,pmt); + FIXME("(%p)->(%p,%p)\n",This,pPin,pmt); if ( This->bOutput ) return E_UNEXPECTED; @@ -559,7 +557,7 @@ HRESULT CPinBaseImpl_InitIPin( ICOM_VTBL(This) = &ipin; This->punkControl = punkControl; This->pHandlers = pHandlers; - This->cbIdLen = sizeof(WCHAR)*(strlenW(pwszId)+1); + This->cbIdLen = sizeof(WCHAR)*(lstrlenW(pwszId)+1); This->pwszId = NULL; This->bOutput = bOutput; This->pmtAcceptTypes = NULL; @@ -986,7 +984,7 @@ HRESULT CPinBaseImpl_SendNewSegment( CPinBaseImpl* This, REFERENCE_TIME rtStart, HRESULT OutputPinSync_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample ) { if ( pImpl->pMemInputPinConnectedTo == NULL ) - return E_UNEXPECTED; + return NOERROR; return IMemInputPin_Receive(pImpl->pMemInputPinConnectedTo,pSample); } diff --git a/dlls/quartz/complist.c b/dlls/quartz/complist.c index 48fca2b9789..efe97b425ab 100644 --- a/dlls/quartz/complist.c +++ b/dlls/quartz/complist.c @@ -8,11 +8,8 @@ #include "windef.h" #include "winbase.h" -#include "wingdi.h" -#include "winuser.h" #include "winerror.h" #include "wine/obj_base.h" -#include "strmif.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); @@ -126,7 +123,7 @@ QUARTZ_CompList* QUARTZ_CompList_Dup( return pNewList; } -HRESULT QUARTZ_CompList_AddComp( +static QUARTZ_CompListItem* QUARTZ_CompList_AllocComp( QUARTZ_CompList* pList, IUnknown* punk, const void* pvData, DWORD dwDataLen ) { @@ -134,7 +131,7 @@ HRESULT QUARTZ_CompList_AddComp( pItem = (QUARTZ_CompListItem*)QUARTZ_AllocMem( sizeof(QUARTZ_CompListItem) ); if ( pItem == NULL ) - return E_OUTOFMEMORY; /* out of memory. */ + return NULL; pItem->pvData = NULL; pItem->dwDataLen = 0; @@ -144,7 +141,7 @@ HRESULT QUARTZ_CompList_AddComp( if ( pItem->pvData == NULL ) { QUARTZ_FreeMem( pItem ); - return E_OUTOFMEMORY; + return NULL; } memcpy( pItem->pvData, pvData, dwDataLen ); pItem->dwDataLen = dwDataLen; @@ -152,6 +149,19 @@ HRESULT QUARTZ_CompList_AddComp( pItem->punk = punk; IUnknown_AddRef(punk); + return pItem; +} + +HRESULT QUARTZ_CompList_AddComp( + QUARTZ_CompList* pList, IUnknown* punk, + const void* pvData, DWORD dwDataLen ) +{ + QUARTZ_CompListItem* pItem; + + pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen ); + if ( pItem == NULL ) + return E_OUTOFMEMORY; + if ( pList->pFirst != NULL ) pList->pFirst->pPrev = pItem; else @@ -163,6 +173,27 @@ HRESULT QUARTZ_CompList_AddComp( return S_OK; } +HRESULT QUARTZ_CompList_AddTailComp( + QUARTZ_CompList* pList, IUnknown* punk, + const void* pvData, DWORD dwDataLen ) +{ + QUARTZ_CompListItem* pItem; + + pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen ); + if ( pItem == NULL ) + return E_OUTOFMEMORY; + + if ( pList->pLast != NULL ) + pList->pLast->pNext = pItem; + else + pList->pFirst = pItem; + pItem->pPrev = pList->pLast; + pList->pLast = pItem; + pItem->pNext = NULL; + + return S_OK; +} + HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk ) { QUARTZ_CompListItem* pCur; @@ -230,12 +261,24 @@ QUARTZ_CompListItem* QUARTZ_CompList_GetFirst( return pList->pFirst; } +QUARTZ_CompListItem* QUARTZ_CompList_GetLast( + QUARTZ_CompList* pList ) +{ + return pList->pLast; +} + QUARTZ_CompListItem* QUARTZ_CompList_GetNext( QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev ) { return pPrev->pNext; } +QUARTZ_CompListItem* QUARTZ_CompList_GetPrev( + QUARTZ_CompList* pList, QUARTZ_CompListItem* pNext ) +{ + return pNext->pPrev; +} + IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem ) { return pItem->punk; diff --git a/dlls/quartz/complist.h b/dlls/quartz/complist.h index 9f02dc2e1df..c0d7f0a9751 100644 --- a/dlls/quartz/complist.h +++ b/dlls/quartz/complist.h @@ -20,6 +20,9 @@ QUARTZ_CompList* QUARTZ_CompList_Dup( HRESULT QUARTZ_CompList_AddComp( QUARTZ_CompList* pList, IUnknown* punk, const void* pvData, DWORD dwDataLen ); +HRESULT QUARTZ_CompList_AddTailComp( + QUARTZ_CompList* pList, IUnknown* punk, + const void* pvData, DWORD dwDataLen ); HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk ); QUARTZ_CompListItem* QUARTZ_CompList_SearchComp( QUARTZ_CompList* pList, IUnknown* punk ); @@ -27,8 +30,12 @@ QUARTZ_CompListItem* QUARTZ_CompList_SearchData( QUARTZ_CompList* pList, const void* pvData, DWORD dwDataLen ); QUARTZ_CompListItem* QUARTZ_CompList_GetFirst( QUARTZ_CompList* pList ); +QUARTZ_CompListItem* QUARTZ_CompList_GetLast( + QUARTZ_CompList* pList ); QUARTZ_CompListItem* QUARTZ_CompList_GetNext( QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev ); +QUARTZ_CompListItem* QUARTZ_CompList_GetPrev( + QUARTZ_CompList* pList, QUARTZ_CompListItem* pNext ); IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem ); const void* QUARTZ_CompList_GetDataPtr( QUARTZ_CompListItem* pItem ); DWORD QUARTZ_CompList_GetDataLength( QUARTZ_CompListItem* pItem ); diff --git a/dlls/quartz/devenum.c b/dlls/quartz/devenum.c index 9832e35a79d..70d46e30231 100644 --- a/dlls/quartz/devenum.c +++ b/dlls/quartz/devenum.c @@ -14,14 +14,7 @@ #include "winuser.h" #include "winreg.h" #include "winerror.h" -#include "wine/obj_base.h" -#include "objidl.h" -#include "oleidl.h" -#include "ocidl.h" #include "strmif.h" -#include "control.h" -#include "uuids.h" -#include "wine/unicode.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); @@ -159,7 +152,7 @@ ICreateDevEnum_fnCreateClassEnumerator(ICreateDevEnum* iface,REFCLSID rclsidDevi 0, KEY_READ, &hKey ) != ERROR_SUCCESS ) return E_FAIL; - dwLen = strlenW(wszPath); + dwLen = lstrlenW(wszPath); wszPath[dwLen++] = '\\'; wszPath[dwLen] = 0; dwNameMax = sizeof(wszPath)/sizeof(wszPath[0]) - dwLen - 8; diff --git a/dlls/quartz/devmon.c b/dlls/quartz/devmon.c index 7ed055d85f9..cef8eb7090c 100644 --- a/dlls/quartz/devmon.c +++ b/dlls/quartz/devmon.c @@ -13,14 +13,12 @@ #include "winuser.h" #include "winreg.h" #include "winerror.h" -#include "wine/obj_base.h" #include "objidl.h" #include "oleidl.h" #include "ocidl.h" #include "oleauto.h" #include "strmif.h" #include "uuids.h" -#include "wine/unicode.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); @@ -366,7 +364,7 @@ static HRESULT CDeviceMoniker_InitIMoniker( pdm->m_hkRoot = hkRoot; pdm->m_pwszPath = NULL; - dwLen = sizeof(WCHAR)*(strlenW(lpKeyPath)+1); + dwLen = sizeof(WCHAR)*(lstrlenW(lpKeyPath)+1); pdm->m_pwszPath = (WCHAR*)QUARTZ_AllocMem( dwLen ); if ( pdm->m_pwszPath == NULL ) return E_OUTOFMEMORY; diff --git a/dlls/quartz/enumunk.c b/dlls/quartz/enumunk.c index 8552bf314ab..e344b8e1b50 100644 --- a/dlls/quartz/enumunk.c +++ b/dlls/quartz/enumunk.c @@ -8,14 +8,9 @@ #include "windef.h" #include "winbase.h" -#include "wingdi.h" -#include "winuser.h" #include "winerror.h" #include "wine/obj_base.h" -#include "wine/obj_oleaut.h" -#include "strmif.h" -#include "control.h" -#include "uuids.h" +#include "wine/obj_misc.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); diff --git a/dlls/quartz/fgevent.c b/dlls/quartz/fgevent.c index 2d25a358f13..a07938ed06c 100644 --- a/dlls/quartz/fgevent.c +++ b/dlls/quartz/fgevent.c @@ -11,8 +11,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" #include "strmif.h" #include "control.h" #include "evcode.h" diff --git a/dlls/quartz/fgidisp.c b/dlls/quartz/fgidisp.c deleted file mode 100644 index d350aefd4df..00000000000 --- a/dlls/quartz/fgidisp.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Implementation of IDispatch for FilterGraph. - * - * FIXME - stub. - * - * hidenori@a2.ctktv.ne.jp - */ - -#include "config.h" - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" -#include "strmif.h" -#include "control.h" -#include "uuids.h" - -#include "debugtools.h" -DEFAULT_DEBUG_CHANNEL(quartz); - -#include "quartz_private.h" -#include "fgraph.h" - - - -static HRESULT WINAPI -IDispatch_fnQueryInterface(IDispatch* iface,REFIID riid,void** ppobj) -{ - CFilterGraph_THIS(iface,disp); - - TRACE("(%p)->()\n",This); - - return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); -} - -static ULONG WINAPI -IDispatch_fnAddRef(IDispatch* iface) -{ - CFilterGraph_THIS(iface,disp); - - TRACE("(%p)->()\n",This); - - return IUnknown_AddRef(This->unk.punkControl); -} - -static ULONG WINAPI -IDispatch_fnRelease(IDispatch* iface) -{ - CFilterGraph_THIS(iface,disp); - - TRACE("(%p)->()\n",This); - - return IUnknown_Release(This->unk.punkControl); -} - -static HRESULT WINAPI -IDispatch_fnGetTypeInfoCount(IDispatch* iface,UINT* pcTypeInfo) -{ - CFilterGraph_THIS(iface,disp); - - FIXME("(%p)->()\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IDispatch_fnGetTypeInfo(IDispatch* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj) -{ - CFilterGraph_THIS(iface,disp); - - FIXME("(%p)->()\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IDispatch_fnGetIDsOfNames(IDispatch* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId) -{ - CFilterGraph_THIS(iface,disp); - - FIXME("(%p)->()\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IDispatch_fnInvoke(IDispatch* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr) -{ - CFilterGraph_THIS(iface,disp); - - FIXME("(%p)->()\n",This); - - return E_NOTIMPL; -} - - - -static ICOM_VTABLE(IDispatch) idispatch = -{ - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - /* IUnknown fields */ - IDispatch_fnQueryInterface, - IDispatch_fnAddRef, - IDispatch_fnRelease, - /* IDispatch fields */ - IDispatch_fnGetTypeInfoCount, - IDispatch_fnGetTypeInfo, - IDispatch_fnGetIDsOfNames, - IDispatch_fnInvoke, -}; - - -HRESULT CFilterGraph_InitIDispatch( CFilterGraph* pfg ) -{ - TRACE("(%p)\n",pfg); - ICOM_VTBL(&pfg->disp) = &idispatch; - - return NOERROR; -} - -void CFilterGraph_UninitIDispatch( CFilterGraph* pfg ) -{ - TRACE("(%p)\n",pfg); -} - diff --git a/dlls/quartz/fgpass.c b/dlls/quartz/fgpass.c index 340a352e2a8..ddd61d1301d 100644 --- a/dlls/quartz/fgpass.c +++ b/dlls/quartz/fgpass.c @@ -13,8 +13,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" #include "strmif.h" #include "control.h" #include "uuids.h" diff --git a/dlls/quartz/fgraph.c b/dlls/quartz/fgraph.c index 6efda0055a5..e545fb54361 100644 --- a/dlls/quartz/fgraph.c +++ b/dlls/quartz/fgraph.c @@ -11,8 +11,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" #include "strmif.h" #include "control.h" #include "uuids.h" @@ -221,3 +219,109 @@ void CFilterGraph_UninitIPersist( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); } + +/*************************************************************************** + * + * CFilterGraph::IDispatch + * + */ + +static HRESULT WINAPI +IDispatch_fnQueryInterface(IDispatch* iface,REFIID riid,void** ppobj) +{ + CFilterGraph_THIS(iface,disp); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IDispatch_fnAddRef(IDispatch* iface) +{ + CFilterGraph_THIS(iface,disp); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IDispatch_fnRelease(IDispatch* iface) +{ + CFilterGraph_THIS(iface,disp); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + +static HRESULT WINAPI +IDispatch_fnGetTypeInfoCount(IDispatch* iface,UINT* pcTypeInfo) +{ + CFilterGraph_THIS(iface,disp); + + FIXME("(%p)->()\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IDispatch_fnGetTypeInfo(IDispatch* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj) +{ + CFilterGraph_THIS(iface,disp); + + FIXME("(%p)->()\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IDispatch_fnGetIDsOfNames(IDispatch* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId) +{ + CFilterGraph_THIS(iface,disp); + + FIXME("(%p)->()\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IDispatch_fnInvoke(IDispatch* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr) +{ + CFilterGraph_THIS(iface,disp); + + FIXME("(%p)->()\n",This); + + return E_NOTIMPL; +} + + + +static ICOM_VTABLE(IDispatch) idispatch = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IDispatch_fnQueryInterface, + IDispatch_fnAddRef, + IDispatch_fnRelease, + /* IDispatch fields */ + IDispatch_fnGetTypeInfoCount, + IDispatch_fnGetTypeInfo, + IDispatch_fnGetIDsOfNames, + IDispatch_fnInvoke, +}; + + +HRESULT CFilterGraph_InitIDispatch( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); + ICOM_VTBL(&pfg->disp) = &idispatch; + + return NOERROR; +} + +void CFilterGraph_UninitIDispatch( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); +} diff --git a/dlls/quartz/fgraph.h b/dlls/quartz/fgraph.h index 93298204174..34a30f098eb 100644 --- a/dlls/quartz/fgraph.h +++ b/dlls/quartz/fgraph.h @@ -125,7 +125,6 @@ typedef struct CFilterGraph /* IFilterGraph2 fields. */ QUARTZ_CompList* m_pFilterList; /* IGraphVersion fields. */ - CRITICAL_SECTION m_csGraphVersion; LONG m_lGraphVersion; /* IMediaControl fields. */ /* IMediaFilter fields. */ diff --git a/dlls/quartz/fmap.c b/dlls/quartz/fmap.c index 9234786bb98..a114ec62bed 100644 --- a/dlls/quartz/fmap.c +++ b/dlls/quartz/fmap.c @@ -1,5 +1,5 @@ /* - * Implementation of CLSID_FilterMapper. + * Implementation of CLSID_FilterMapper and CLSID_FilterMapper2. * * FIXME - stub. * @@ -14,10 +14,7 @@ #include "winuser.h" #include "winreg.h" #include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" #include "strmif.h" -#include "control.h" #include "uuids.h" #include "debugtools.h" @@ -35,7 +32,7 @@ DEFAULT_DEBUG_CHANNEL(quartz); */ /* can I use offsetof safely? - FIXME? */ -static QUARTZ_IFEntry IFEntries[] = +static QUARTZ_IFEntry FMapIFEntries[] = { { &IID_IFilterMapper, offsetof(CFilterMapper,fmap)-offsetof(CFilterMapper,unk) }, }; @@ -67,8 +64,8 @@ HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj) return hr; } - pfm->unk.pEntries = IFEntries; - pfm->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); + pfm->unk.pEntries = FMapIFEntries; + pfm->unk.dwEntries = sizeof(FMapIFEntries)/sizeof(FMapIFEntries[0]); pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper; *ppobj = (void*)(&pfm->unk); @@ -254,3 +251,212 @@ void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm ) { TRACE("(%p)\n",pfm); } + + +/*************************************************************************** + * + * new/delete for CLSID_FilterMapper2 + * + */ + +/* can I use offsetof safely? - FIXME? */ +static QUARTZ_IFEntry FMap2IFEntries[] = +{ + { &IID_IFilterMapper2, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) }, + { &IID_IFilterMapper3, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) }, +}; + + +static void QUARTZ_DestroyFilterMapper2(IUnknown* punk) +{ + CFilterMapper2_THIS(punk,unk); + + CFilterMapper2_UninitIFilterMapper3( This ); +} + +HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj) +{ + CFilterMapper2* pfm; + HRESULT hr; + + TRACE("(%p,%p)\n",punkOuter,ppobj); + + pfm = (CFilterMapper2*)QUARTZ_AllocObj( sizeof(CFilterMapper2) ); + if ( pfm == NULL ) + return E_OUTOFMEMORY; + + QUARTZ_IUnkInit( &pfm->unk, punkOuter ); + hr = CFilterMapper2_InitIFilterMapper3( pfm ); + if ( FAILED(hr) ) + { + QUARTZ_FreeObj( pfm ); + return hr; + } + + pfm->unk.pEntries = FMap2IFEntries; + pfm->unk.dwEntries = sizeof(FMap2IFEntries)/sizeof(FMap2IFEntries[0]); + pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper2; + + *ppobj = (void*)(&pfm->unk); + + return S_OK; +} + +/*************************************************************************** + * + * CLSID_FilterMapper2::IFilterMapper3 + * + */ + + +static HRESULT WINAPI +IFilterMapper3_fnQueryInterface(IFilterMapper3* iface,REFIID riid,void** ppobj) +{ + CFilterMapper2_THIS(iface,fmap3); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IFilterMapper3_fnAddRef(IFilterMapper3* iface) +{ + CFilterMapper2_THIS(iface,fmap3); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IFilterMapper3_fnRelease(IFilterMapper3* iface) +{ + CFilterMapper2_THIS(iface,fmap3); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + +static HRESULT WINAPI +IFilterMapper3_fnCreateCategory(IFilterMapper3* iface,REFCLSID rclsidCategory,DWORD dwMerit,LPCWSTR lpwszDesc) +{ + CFilterMapper2_THIS(iface,fmap3); + + FIXME("(%p)->(%s,%lu,%s) stub!\n",This, + debugstr_guid(rclsidCategory), + (unsigned long)dwMerit,debugstr_w(lpwszDesc)); + + return E_NOTIMPL; +} + + +static HRESULT WINAPI +IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter) +{ + CFilterMapper2_THIS(iface,fmap3); + + FIXME("(%p)->(%s,%s,%s) stub!\n",This, + debugstr_guid(pclsidCategory), + debugstr_w(lpwszInst), + debugstr_guid(rclsidFilter)); + + if ( pclsidCategory == NULL ) + pclsidCategory = &CLSID_LegacyAmFilterCategory; + + /* FIXME */ + return QUARTZ_RegisterAMovieFilter( + pclsidCategory, + rclsidFilter, + NULL, 0, + NULL, lpwszInst, FALSE ); +} + + +static HRESULT WINAPI +IFilterMapper3_fnRegisterFilter(IFilterMapper3* iface,REFCLSID rclsidFilter,LPCWSTR lpName,IMoniker** ppMoniker,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,const REGFILTER2* pRF2) +{ + CFilterMapper2_THIS(iface,fmap3); + + FIXME( "(%p)->(%s,%s,%p,%s,%s,%p) stub!\n",This, + debugstr_guid(rclsidFilter),debugstr_w(lpName), + ppMoniker,debugstr_guid(pclsidCategory), + debugstr_w(lpwszInst),pRF2 ); + + if ( lpName == NULL || pRF2 == NULL ) + return E_POINTER; + + if ( ppMoniker != NULL ) + { + FIXME( "ppMoniker != NULL - not implemented!\n" ); + return E_NOTIMPL; + } + + if ( pclsidCategory == NULL ) + pclsidCategory = &CLSID_LegacyAmFilterCategory; + + /* FIXME!! - all members in REGFILTER2 are ignored ! */ + + return QUARTZ_RegisterAMovieFilter( + pclsidCategory, + rclsidFilter, + NULL, 0, + lpName, lpwszInst, TRUE ); +} + + +static HRESULT WINAPI +IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,IEnumMoniker** ppMoniker,DWORD dwFlags,BOOL bExactMatch,DWORD dwMerit,BOOL bInputNeeded,DWORD cInputTypes,const GUID* pguidInputTypes,const REGPINMEDIUM* pPinMediumIn,const CLSID* pPinCategoryIn,BOOL bRender,BOOL bOutputNeeded,DWORD cOutputTypes,const GUID* pguidOutputTypes,const REGPINMEDIUM* pPinMediumOut,const CLSID* pPinCategoryOut) +{ + CFilterMapper2_THIS(iface,fmap3); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IFilterMapper3_fnGetICreateDevEnum(IFilterMapper3* iface,ICreateDevEnum** ppDevEnum) +{ + CFilterMapper2_THIS(iface,fmap3); + + /* undocumented */ + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + + + + +static ICOM_VTABLE(IFilterMapper3) ifmap3 = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IFilterMapper3_fnQueryInterface, + IFilterMapper3_fnAddRef, + IFilterMapper3_fnRelease, + /* IFilterMapper2 fields */ + IFilterMapper3_fnCreateCategory, + IFilterMapper3_fnUnregisterFilter, + IFilterMapper3_fnRegisterFilter, + IFilterMapper3_fnEnumMatchingFilters, + /* IFilterMapper3 fields */ + IFilterMapper3_fnGetICreateDevEnum, +}; + + +HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* pfm ) +{ + TRACE("(%p)\n",pfm); + ICOM_VTBL(&pfm->fmap3) = &ifmap3; + + return NOERROR; +} + +void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* pfm ) +{ + TRACE("(%p)\n",pfm); +} + diff --git a/dlls/quartz/fmap.h b/dlls/quartz/fmap.h index c21cc2e8076..61d249f055f 100644 --- a/dlls/quartz/fmap.h +++ b/dlls/quartz/fmap.h @@ -33,5 +33,37 @@ HRESULT CFilterMapper_InitIFilterMapper( CFilterMapper* pfm ); void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm ); -#endif /* WINE_DSHOW_FMAP_H */ +/* + implements CLSID_FilterMapper2. + + - At least, the following interfaces should be implemented: + + IUnknown + + IFilterMapper2 - IFilterMapper3 + */ + +#include "iunk.h" + + +typedef struct FM2_IFilterMapper3Impl +{ + ICOM_VFIELD(IFilterMapper3); +} FM2_IFilterMapper3Impl; + +typedef struct CFilterMapper2 +{ + QUARTZ_IUnkImpl unk; + FM2_IFilterMapper3Impl fmap3; + /* IFilterMapper3 fields */ +} CFilterMapper2; + +#define CFilterMapper2_THIS(iface,member) CFilterMapper2* This = ((CFilterMapper2*)(((char*)iface)-offsetof(CFilterMapper2,member))) + +HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj); + + +HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* psde ); +void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* psde ); + +#endif /* WINE_DSHOW_FMAP_H */ diff --git a/dlls/quartz/fmap2.c b/dlls/quartz/fmap2.c deleted file mode 100644 index 315d2317404..00000000000 --- a/dlls/quartz/fmap2.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Implementation of CLSID_FilterMapper2. - * - * FIXME - stub. - * - * hidenori@a2.ctktv.ne.jp - */ - -#include "config.h" - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "winreg.h" -#include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" -#include "strmif.h" -#include "control.h" -#include "uuids.h" - -#include "debugtools.h" -DEFAULT_DEBUG_CHANNEL(quartz); - -#include "quartz_private.h" -#include "fmap2.h" -#include "regsvr.h" - - -/*************************************************************************** - * - * new/delete for CLSID_FilterMapper2 - * - */ - -/* can I use offsetof safely? - FIXME? */ -static QUARTZ_IFEntry IFEntries[] = -{ - { &IID_IFilterMapper2, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) }, - { &IID_IFilterMapper3, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) }, -}; - - -static void QUARTZ_DestroyFilterMapper2(IUnknown* punk) -{ - CFilterMapper2_THIS(punk,unk); - - CFilterMapper2_UninitIFilterMapper3( This ); -} - -HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj) -{ - CFilterMapper2* pfm; - HRESULT hr; - - TRACE("(%p,%p)\n",punkOuter,ppobj); - - pfm = (CFilterMapper2*)QUARTZ_AllocObj( sizeof(CFilterMapper2) ); - if ( pfm == NULL ) - return E_OUTOFMEMORY; - - QUARTZ_IUnkInit( &pfm->unk, punkOuter ); - hr = CFilterMapper2_InitIFilterMapper3( pfm ); - if ( FAILED(hr) ) - { - QUARTZ_FreeObj( pfm ); - return hr; - } - - pfm->unk.pEntries = IFEntries; - pfm->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); - pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper2; - - *ppobj = (void*)(&pfm->unk); - - return S_OK; -} - -/*************************************************************************** - * - * CLSID_FilterMapper2::IFilterMapper3 - * - */ - - -static HRESULT WINAPI -IFilterMapper3_fnQueryInterface(IFilterMapper3* iface,REFIID riid,void** ppobj) -{ - CFilterMapper2_THIS(iface,fmap3); - - TRACE("(%p)->()\n",This); - - return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); -} - -static ULONG WINAPI -IFilterMapper3_fnAddRef(IFilterMapper3* iface) -{ - CFilterMapper2_THIS(iface,fmap3); - - TRACE("(%p)->()\n",This); - - return IUnknown_AddRef(This->unk.punkControl); -} - -static ULONG WINAPI -IFilterMapper3_fnRelease(IFilterMapper3* iface) -{ - CFilterMapper2_THIS(iface,fmap3); - - TRACE("(%p)->()\n",This); - - return IUnknown_Release(This->unk.punkControl); -} - -static HRESULT WINAPI -IFilterMapper3_fnCreateCategory(IFilterMapper3* iface,REFCLSID rclsidCategory,DWORD dwMerit,LPCWSTR lpwszDesc) -{ - CFilterMapper2_THIS(iface,fmap3); - - FIXME("(%p)->(%s,%lu,%s) stub!\n",This, - debugstr_guid(rclsidCategory), - (unsigned long)dwMerit,debugstr_w(lpwszDesc)); - - return E_NOTIMPL; -} - - -static HRESULT WINAPI -IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter) -{ - CFilterMapper2_THIS(iface,fmap3); - - FIXME("(%p)->(%s,%s,%s) stub!\n",This, - debugstr_guid(pclsidCategory), - debugstr_w(lpwszInst), - debugstr_guid(rclsidFilter)); - - if ( pclsidCategory == NULL ) - pclsidCategory = &CLSID_LegacyAmFilterCategory; - - /* FIXME */ - return QUARTZ_RegisterAMovieFilter( - pclsidCategory, - rclsidFilter, - NULL, 0, - NULL, lpwszInst, FALSE ); -} - - -static HRESULT WINAPI -IFilterMapper3_fnRegisterFilter(IFilterMapper3* iface,REFCLSID rclsidFilter,LPCWSTR lpName,IMoniker** ppMoniker,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,const REGFILTER2* pRF2) -{ - CFilterMapper2_THIS(iface,fmap3); - - FIXME( "(%p)->(%s,%s,%p,%s,%s,%p) stub!\n",This, - debugstr_guid(rclsidFilter),debugstr_w(lpName), - ppMoniker,debugstr_guid(pclsidCategory), - debugstr_w(lpwszInst),pRF2 ); - - if ( lpName == NULL || pRF2 == NULL ) - return E_POINTER; - - if ( ppMoniker != NULL ) - { - FIXME( "ppMoniker != NULL - not implemented!\n" ); - return E_NOTIMPL; - } - - if ( pclsidCategory == NULL ) - pclsidCategory = &CLSID_LegacyAmFilterCategory; - - /* FIXME!! - all members in REGFILTER2 are ignored ! */ - - return QUARTZ_RegisterAMovieFilter( - pclsidCategory, - rclsidFilter, - NULL, 0, - lpName, lpwszInst, TRUE ); -} - - -static HRESULT WINAPI -IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,IEnumMoniker** ppMoniker,DWORD dwFlags,BOOL bExactMatch,DWORD dwMerit,BOOL bInputNeeded,DWORD cInputTypes,const GUID* pguidInputTypes,const REGPINMEDIUM* pPinMediumIn,const CLSID* pPinCategoryIn,BOOL bRender,BOOL bOutputNeeded,DWORD cOutputTypes,const GUID* pguidOutputTypes,const REGPINMEDIUM* pPinMediumOut,const CLSID* pPinCategoryOut) -{ - CFilterMapper2_THIS(iface,fmap3); - - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IFilterMapper3_fnGetICreateDevEnum(IFilterMapper3* iface,ICreateDevEnum** ppDevEnum) -{ - CFilterMapper2_THIS(iface,fmap3); - - /* undocumented */ - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; -} - - - - -static ICOM_VTABLE(IFilterMapper3) ifmap3 = -{ - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - /* IUnknown fields */ - IFilterMapper3_fnQueryInterface, - IFilterMapper3_fnAddRef, - IFilterMapper3_fnRelease, - /* IFilterMapper2 fields */ - IFilterMapper3_fnCreateCategory, - IFilterMapper3_fnUnregisterFilter, - IFilterMapper3_fnRegisterFilter, - IFilterMapper3_fnEnumMatchingFilters, - /* IFilterMapper3 fields */ - IFilterMapper3_fnGetICreateDevEnum, -}; - - -HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* pfm ) -{ - TRACE("(%p)\n",pfm); - ICOM_VTBL(&pfm->fmap3) = &ifmap3; - - return NOERROR; -} - -void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* pfm ) -{ - TRACE("(%p)\n",pfm); -} - diff --git a/dlls/quartz/fmap2.h b/dlls/quartz/fmap2.h deleted file mode 100644 index 6cf7718c577..00000000000 --- a/dlls/quartz/fmap2.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef WINE_DSHOW_FMAP2_H -#define WINE_DSHOW_FMAP2_H - -/* - implements CLSID_FilterMapper2. - - - At least, the following interfaces should be implemented: - - IUnknown - + IFilterMapper2 - IFilterMapper3 - */ - -#include "iunk.h" - - -typedef struct FM2_IFilterMapper3Impl -{ - ICOM_VFIELD(IFilterMapper3); -} FM2_IFilterMapper3Impl; - -typedef struct CFilterMapper2 -{ - QUARTZ_IUnkImpl unk; - FM2_IFilterMapper3Impl fmap3; - /* IFilterMapper3 fields */ -} CFilterMapper2; - -#define CFilterMapper2_THIS(iface,member) CFilterMapper2* This = ((CFilterMapper2*)(((char*)iface)-offsetof(CFilterMapper2,member))) - -HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj); - - -HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* psde ); -void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* psde ); - - -#endif /* WINE_DSHOW_FMAP2_H */ - diff --git a/dlls/quartz/ifgraph.c b/dlls/quartz/ifgraph.c index ae807475ceb..e86979e44a8 100644 --- a/dlls/quartz/ifgraph.c +++ b/dlls/quartz/ifgraph.c @@ -1,5 +1,6 @@ /* - * Implementation of IFilterGraph. + * Implementation of IFilterGraph and related interfaces + * + IGraphVersion, IGraphConfig * * FIXME - create a thread to process some methods correctly. * @@ -17,13 +18,10 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" #include "strmif.h" #include "control.h" #include "uuids.h" #include "vfwmsgs.h" -#include "wine/unicode.h" #include "evcode.h" #include "debugtools.h" @@ -86,15 +84,17 @@ static HRESULT CFilterGraph_GraphChanged( CFilterGraph* This ) IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This), EC_GRAPH_CHANGED, 0, 0); - EnterCriticalSection( &This->m_csGraphVersion ); This->m_lGraphVersion ++; - LeaveCriticalSection( &This->m_csGraphVersion ); return NOERROR; } -/****************************************************************************/ +/*************************************************************************** + * + * CFilterGraph::IFilterGraph2 methods + * + */ static HRESULT WINAPI IFilterGraph2_fnQueryInterface(IFilterGraph2* iface,REFIID riid,void** ppobj) @@ -155,13 +155,13 @@ IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pNa { pItem = QUARTZ_CompList_SearchData( This->m_pFilterList, - pName, sizeof(WCHAR)*(strlenW(pName)+1) ); + pName, sizeof(WCHAR)*(lstrlenW(pName)+1) ); if ( pItem == NULL ) goto name_ok; hrSucceeded = VFW_S_DUPLICATE_NAME; - iLen = strlenW(pName); + iLen = lstrlenW(pName); if ( iLen > 32 ) iLen = 32; memcpy( info.achName, pName, sizeof(WCHAR)*iLen ); @@ -174,7 +174,7 @@ IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pNa if ( FAILED(hr) ) goto end; - iLen = strlenW(info.achName); + iLen = lstrlenW(info.achName); pItem = QUARTZ_CompList_SearchData( This->m_pFilterList, info.achName, sizeof(WCHAR)*(iLen+1) ); @@ -186,7 +186,7 @@ IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pNa } /* generate modified names for this filter.. */ - iLen = strlenW(info.achName); + iLen = lstrlenW(info.achName); if ( iLen > 32 ) iLen = 32; info.achName[iLen++] = ' '; @@ -215,7 +215,7 @@ name_ok: /* register this filter. */ hr = QUARTZ_CompList_AddComp( This->m_pFilterList, (IUnknown*)pFilter, - pName, sizeof(WCHAR)*(strlenW(pName)+1) ); + pName, sizeof(WCHAR)*(lstrlenW(pName)+1) ); if ( FAILED(hr) ) goto end; @@ -325,7 +325,7 @@ IFilterGraph2_fnFindFilterByName(IFilterGraph2* iface,LPCWSTR pName,IBaseFilter* pItem = QUARTZ_CompList_SearchData( This->m_pFilterList, - pName, sizeof(WCHAR)*(strlenW(pName)+1) ); + pName, sizeof(WCHAR)*(lstrlenW(pName)+1) ); if ( pItem != NULL ) { *ppFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr(pItem); @@ -346,6 +346,7 @@ IFilterGraph2_fnConnectDirect(IFilterGraph2* iface,IPin* pOut,IPin* pIn,const AM PIN_INFO infoOut; FILTER_INFO finfoIn; FILTER_INFO finfoOut; + FILTER_STATE fs; HRESULT hr; TRACE( "(%p)->(%p,%p,%p)\n",This,pOut,pIn,pmt ); @@ -357,6 +358,14 @@ IFilterGraph2_fnConnectDirect(IFilterGraph2* iface,IPin* pOut,IPin* pIn,const AM QUARTZ_CompList_Lock( This->m_pFilterList ); + hr = IMediaFilter_GetState(CFilterGraph_IMediaFilter(This),0,&fs); + if ( hr == VFW_S_STATE_INTERMEDIATE ) + hr = VFW_E_STATE_CHANGED; + if ( fs != State_Stopped ) + hr = VFW_E_NOT_STOPPED; + if ( FAILED(hr) ) + goto end; + hr = IPin_QueryPinInfo(pIn,&infoIn); if ( FAILED(hr) ) goto end; @@ -482,7 +491,7 @@ IFilterGraph2_fnSetDefaultSyncSource(IFilterGraph2* iface) FIXME( "(%p)->() stub!\n", This ); - /* FIXME - search all filters. */ + /* FIXME - search all filters from renderer. */ hr = QUARTZ_CreateSystemClock( NULL, (void**)&punk ); if ( FAILED(hr) ) @@ -668,7 +677,9 @@ IFilterGraph2_fnReconnectEx(IFilterGraph2* iface,IPin* pPin,const AM_MEDIA_TYPE* /* reconnect asynchronously. */ + QUARTZ_CompList_Lock( This->m_pFilterList ); hr = CFilterGraph_GraphChanged(This); + QUARTZ_CompList_Unlock( This->m_pFilterList ); return E_NOTIMPL; } @@ -747,3 +758,274 @@ void CFilterGraph_UninitIFilterGraph2( CFilterGraph* pfg ) QUARTZ_CompList_Free( pfg->m_pFilterList ); } + +/*************************************************************************** + * + * CFilterGraph::IGraphVersion methods + * + */ + +static HRESULT WINAPI +IGraphVersion_fnQueryInterface(IGraphVersion* iface,REFIID riid,void** ppobj) +{ + CFilterGraph_THIS(iface,graphversion); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IGraphVersion_fnAddRef(IGraphVersion* iface) +{ + CFilterGraph_THIS(iface,graphversion); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IGraphVersion_fnRelease(IGraphVersion* iface) +{ + CFilterGraph_THIS(iface,graphversion); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + + +static HRESULT WINAPI +IGraphVersion_fnQueryVersion(IGraphVersion* iface,LONG* plVersion) +{ + CFilterGraph_THIS(iface,graphversion); + + TRACE("(%p)->(%p)\n",This,plVersion); + + if ( plVersion == NULL ) + return E_POINTER; + + QUARTZ_CompList_Lock( This->m_pFilterList ); + *plVersion = This->m_lGraphVersion; + QUARTZ_CompList_Unlock( This->m_pFilterList ); + + return NOERROR; +} + + +static ICOM_VTABLE(IGraphVersion) igraphversion = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IGraphVersion_fnQueryInterface, + IGraphVersion_fnAddRef, + IGraphVersion_fnRelease, + /* IGraphVersion fields */ + IGraphVersion_fnQueryVersion, +}; + + + +HRESULT CFilterGraph_InitIGraphVersion( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); + ICOM_VTBL(&pfg->graphversion) = &igraphversion; + + pfg->m_lGraphVersion = 1; + + return NOERROR; +} + +void CFilterGraph_UninitIGraphVersion( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); +} + +/*************************************************************************** + * + * CFilterGraph::IGraphConfig methods + * + */ + +static HRESULT WINAPI +IGraphConfig_fnQueryInterface(IGraphConfig* iface,REFIID riid,void** ppobj) +{ + CFilterGraph_THIS(iface,grphconf); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IGraphConfig_fnAddRef(IGraphConfig* iface) +{ + CFilterGraph_THIS(iface,grphconf); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IGraphConfig_fnRelease(IGraphConfig* iface) +{ + CFilterGraph_THIS(iface,grphconf); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + + + +static HRESULT WINAPI +IGraphConfig_fnReconnect(IGraphConfig* iface,IPin* pOut,IPin* pIn,const AM_MEDIA_TYPE* pmt,IBaseFilter* pFilter,HANDLE hAbort,DWORD dwFlags) +{ + CFilterGraph_THIS(iface,grphconf); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IGraphConfig_fnReconfigure(IGraphConfig* iface,IGraphConfigCallback* pCallback,PVOID pvParam,DWORD dwFlags,HANDLE hAbort) +{ + CFilterGraph_THIS(iface,grphconf); + HRESULT hr; + + FIXME("(%p)->(%p,%p,%08lx,%08x) stub!\n",This,pCallback,pvParam,dwFlags,hAbort); + + QUARTZ_CompList_Lock( This->m_pFilterList ); + EnterCriticalSection( &This->m_csGraphState ); + + hr = IGraphConfigCallback_Reconfigure(pCallback,pvParam,dwFlags); + + LeaveCriticalSection( &This->m_csGraphState ); + QUARTZ_CompList_Unlock( This->m_pFilterList ); + + return hr; +} + +static HRESULT WINAPI +IGraphConfig_fnAddFilterToCache(IGraphConfig* iface,IBaseFilter* pFilter) +{ + CFilterGraph_THIS(iface,grphconf); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IGraphConfig_fnEnumCacheFilter(IGraphConfig* iface,IEnumFilters** ppenum) +{ + CFilterGraph_THIS(iface,grphconf); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IGraphConfig_fnRemoveFilterFromCache(IGraphConfig* iface,IBaseFilter* pFilter) +{ + CFilterGraph_THIS(iface,grphconf); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IGraphConfig_fnGetStartTime(IGraphConfig* iface,REFERENCE_TIME* prt) +{ + CFilterGraph_THIS(iface,grphconf); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IGraphConfig_fnPushThroughData(IGraphConfig* iface,IPin* pOut,IPinConnection* pConn,HANDLE hAbort) +{ + CFilterGraph_THIS(iface,grphconf); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IGraphConfig_fnSetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags) +{ + CFilterGraph_THIS(iface,grphconf); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IGraphConfig_fnGetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD* pdwFlags) +{ + CFilterGraph_THIS(iface,grphconf); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IGraphConfig_fnRemoveFilterEx(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags) +{ + CFilterGraph_THIS(iface,grphconf); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + + + + + +static ICOM_VTABLE(IGraphConfig) igraphconfig = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IGraphConfig_fnQueryInterface, + IGraphConfig_fnAddRef, + IGraphConfig_fnRelease, + /* IGraphConfig fields */ + IGraphConfig_fnReconnect, + IGraphConfig_fnReconfigure, + IGraphConfig_fnAddFilterToCache, + IGraphConfig_fnEnumCacheFilter, + IGraphConfig_fnRemoveFilterFromCache, + IGraphConfig_fnGetStartTime, + IGraphConfig_fnPushThroughData, + IGraphConfig_fnSetFilterFlags, + IGraphConfig_fnGetFilterFlags, + IGraphConfig_fnRemoveFilterEx, +}; + + + +HRESULT CFilterGraph_InitIGraphConfig( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); + ICOM_VTBL(&pfg->grphconf) = &igraphconfig; + + return NOERROR; +} + +void CFilterGraph_UninitIGraphConfig( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); +} + + diff --git a/dlls/quartz/igconfig.c b/dlls/quartz/igconfig.c deleted file mode 100644 index 4ab9b089c34..00000000000 --- a/dlls/quartz/igconfig.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Implementation of IGraphConfig for FilterGraph. - * - * FIXME - stub. - * - * hidenori@a2.ctktv.ne.jp - */ - -#include "config.h" - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" -#include "strmif.h" -#include "control.h" -#include "uuids.h" - -#include "debugtools.h" -DEFAULT_DEBUG_CHANNEL(quartz); - -#include "quartz_private.h" -#include "fgraph.h" - - - -static HRESULT WINAPI -IGraphConfig_fnQueryInterface(IGraphConfig* iface,REFIID riid,void** ppobj) -{ - CFilterGraph_THIS(iface,grphconf); - - TRACE("(%p)->()\n",This); - - return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); -} - -static ULONG WINAPI -IGraphConfig_fnAddRef(IGraphConfig* iface) -{ - CFilterGraph_THIS(iface,grphconf); - - TRACE("(%p)->()\n",This); - - return IUnknown_AddRef(This->unk.punkControl); -} - -static ULONG WINAPI -IGraphConfig_fnRelease(IGraphConfig* iface) -{ - CFilterGraph_THIS(iface,grphconf); - - TRACE("(%p)->()\n",This); - - return IUnknown_Release(This->unk.punkControl); -} - - - -static HRESULT WINAPI -IGraphConfig_fnReconnect(IGraphConfig* iface,IPin* pOut,IPin* pIn,const AM_MEDIA_TYPE* pmt,IBaseFilter* pFilter,HANDLE hAbort,DWORD dwFlags) -{ - CFilterGraph_THIS(iface,grphconf); - - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IGraphConfig_fnReconfigure(IGraphConfig* iface,IGraphConfigCallback* pCallback,PVOID pvParam,DWORD dwFlags,HANDLE hAbort) -{ - CFilterGraph_THIS(iface,grphconf); - HRESULT hr; - - FIXME("(%p)->(%p,%p,%08lx,%08x) stub!\n",This,pCallback,pvParam,dwFlags,hAbort); - - QUARTZ_CompList_Lock( This->m_pFilterList ); - EnterCriticalSection( &This->m_csGraphState ); - - hr = IGraphConfigCallback_Reconfigure(pCallback,pvParam,dwFlags); - - LeaveCriticalSection( &This->m_csGraphState ); - QUARTZ_CompList_Unlock( This->m_pFilterList ); - - return hr; -} - -static HRESULT WINAPI -IGraphConfig_fnAddFilterToCache(IGraphConfig* iface,IBaseFilter* pFilter) -{ - CFilterGraph_THIS(iface,grphconf); - - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IGraphConfig_fnEnumCacheFilter(IGraphConfig* iface,IEnumFilters** ppenum) -{ - CFilterGraph_THIS(iface,grphconf); - - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IGraphConfig_fnRemoveFilterFromCache(IGraphConfig* iface,IBaseFilter* pFilter) -{ - CFilterGraph_THIS(iface,grphconf); - - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IGraphConfig_fnGetStartTime(IGraphConfig* iface,REFERENCE_TIME* prt) -{ - CFilterGraph_THIS(iface,grphconf); - - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IGraphConfig_fnPushThroughData(IGraphConfig* iface,IPin* pOut,IPinConnection* pConn,HANDLE hAbort) -{ - CFilterGraph_THIS(iface,grphconf); - - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IGraphConfig_fnSetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags) -{ - CFilterGraph_THIS(iface,grphconf); - - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IGraphConfig_fnGetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD* pdwFlags) -{ - CFilterGraph_THIS(iface,grphconf); - - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI -IGraphConfig_fnRemoveFilterEx(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags) -{ - CFilterGraph_THIS(iface,grphconf); - - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; -} - - - - - -static ICOM_VTABLE(IGraphConfig) igraphconfig = -{ - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - /* IUnknown fields */ - IGraphConfig_fnQueryInterface, - IGraphConfig_fnAddRef, - IGraphConfig_fnRelease, - /* IGraphConfig fields */ - IGraphConfig_fnReconnect, - IGraphConfig_fnReconfigure, - IGraphConfig_fnAddFilterToCache, - IGraphConfig_fnEnumCacheFilter, - IGraphConfig_fnRemoveFilterFromCache, - IGraphConfig_fnGetStartTime, - IGraphConfig_fnPushThroughData, - IGraphConfig_fnSetFilterFlags, - IGraphConfig_fnGetFilterFlags, - IGraphConfig_fnRemoveFilterEx, -}; - - - -HRESULT CFilterGraph_InitIGraphConfig( CFilterGraph* pfg ) -{ - TRACE("(%p)\n",pfg); - ICOM_VTBL(&pfg->grphconf) = &igraphconfig; - - return NOERROR; -} - -void CFilterGraph_UninitIGraphConfig( CFilterGraph* pfg ) -{ - TRACE("(%p)\n",pfg); -} - diff --git a/dlls/quartz/igrver.c b/dlls/quartz/igrver.c deleted file mode 100644 index 3fee68c5794..00000000000 --- a/dlls/quartz/igrver.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Implementation of IGraphVersion for FilterGraph. - * - * FIXME - stub. - * - * hidenori@a2.ctktv.ne.jp - */ - -#include "config.h" - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" -#include "strmif.h" -#include "control.h" -#include "uuids.h" - -#include "debugtools.h" -DEFAULT_DEBUG_CHANNEL(quartz); - -#include "quartz_private.h" -#include "fgraph.h" - - - -static HRESULT WINAPI -IGraphVersion_fnQueryInterface(IGraphVersion* iface,REFIID riid,void** ppobj) -{ - CFilterGraph_THIS(iface,graphversion); - - TRACE("(%p)->()\n",This); - - return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); -} - -static ULONG WINAPI -IGraphVersion_fnAddRef(IGraphVersion* iface) -{ - CFilterGraph_THIS(iface,graphversion); - - TRACE("(%p)->()\n",This); - - return IUnknown_AddRef(This->unk.punkControl); -} - -static ULONG WINAPI -IGraphVersion_fnRelease(IGraphVersion* iface) -{ - CFilterGraph_THIS(iface,graphversion); - - TRACE("(%p)->()\n",This); - - return IUnknown_Release(This->unk.punkControl); -} - - -static HRESULT WINAPI -IGraphVersion_fnQueryVersion(IGraphVersion* iface,LONG* plVersion) -{ - CFilterGraph_THIS(iface,graphversion); - - TRACE("(%p)->(%p)\n",This,plVersion); - - if ( plVersion == NULL ) - return E_POINTER; - - EnterCriticalSection( &This->m_csGraphVersion ); - *plVersion = This->m_lGraphVersion; - LeaveCriticalSection( &This->m_csGraphVersion ); - - return NOERROR; -} - - -static ICOM_VTABLE(IGraphVersion) igraphversion = -{ - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - /* IUnknown fields */ - IGraphVersion_fnQueryInterface, - IGraphVersion_fnAddRef, - IGraphVersion_fnRelease, - /* IGraphVersion fields */ - IGraphVersion_fnQueryVersion, -}; - - - -HRESULT CFilterGraph_InitIGraphVersion( CFilterGraph* pfg ) -{ - TRACE("(%p)\n",pfg); - ICOM_VTBL(&pfg->graphversion) = &igraphversion; - - InitializeCriticalSection( &pfg->m_csGraphVersion ); - pfg->m_lGraphVersion = 1; - - return NOERROR; -} - -void CFilterGraph_UninitIGraphVersion( CFilterGraph* pfg ) -{ - TRACE("(%p)\n",pfg); - - DeleteCriticalSection( &pfg->m_csGraphVersion ); -} - diff --git a/dlls/quartz/imcntl.c b/dlls/quartz/imcntl.c index 512600c0784..467210cdacc 100644 --- a/dlls/quartz/imcntl.c +++ b/dlls/quartz/imcntl.c @@ -13,8 +13,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" #include "oleauto.h" #include "strmif.h" #include "control.h" diff --git a/dlls/quartz/imfilter.c b/dlls/quartz/imfilter.c index a602852ea2a..08a5c2a440d 100644 --- a/dlls/quartz/imfilter.c +++ b/dlls/quartz/imfilter.c @@ -13,8 +13,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" #include "strmif.h" #include "control.h" #include "uuids.h" diff --git a/dlls/quartz/impos.c b/dlls/quartz/impos.c index 38d69030c4e..24bf13e74d8 100644 --- a/dlls/quartz/impos.c +++ b/dlls/quartz/impos.c @@ -13,8 +13,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" #include "strmif.h" #include "control.h" #include "uuids.h" diff --git a/dlls/quartz/imseek.c b/dlls/quartz/imseek.c index 2a515fb7388..3489329ab3d 100644 --- a/dlls/quartz/imseek.c +++ b/dlls/quartz/imseek.c @@ -14,8 +14,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" #include "strmif.h" #include "control.h" #include "uuids.h" diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c index fb8421c2719..5d6462634f6 100644 --- a/dlls/quartz/main.c +++ b/dlls/quartz/main.c @@ -14,7 +14,6 @@ #include "winnls.h" #include "mmsystem.h" #include "ole2.h" -#include "wine/obj_oleaut.h" #include "strmif.h" #include "control.h" #include "uuids.h" @@ -23,17 +22,19 @@ #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); +#include "initguid.h" + #include "quartz_private.h" #include "fgraph.h" #include "sysclock.h" #include "memalloc.h" #include "devenum.h" #include "fmap.h" -#include "fmap2.h" #include "seekpass.h" #include "audren.h" #include "vidren.h" #include "parser.h" +#include "asyncsrc.h" typedef struct QUARTZ_CLASSENTRY { @@ -80,6 +81,9 @@ static const QUARTZ_CLASSENTRY QUARTZ_ClassList[] = { &CLSID_AudioRender, &QUARTZ_CreateAudioRenderer }, { &CLSID_VideoRenderer, &QUARTZ_CreateVideoRenderer }, { &CLSID_quartzWaveParser, &QUARTZ_CreateWaveParser }, + { &CLSID_AviSplitter, &QUARTZ_CreateAVISplitter }, + { &CLSID_AsyncReader, &QUARTZ_CreateAsyncReader }, + { &CLSID_URLReader, &QUARTZ_CreateURLReader }, { NULL, NULL }, }; diff --git a/dlls/quartz/memalloc.c b/dlls/quartz/memalloc.c index 31e0e6b9152..133ea4665f7 100644 --- a/dlls/quartz/memalloc.c +++ b/dlls/quartz/memalloc.c @@ -11,7 +11,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" #include "strmif.h" #include "uuids.h" diff --git a/dlls/quartz/mtype.c b/dlls/quartz/mtype.c index 0510fdfc1ff..2f61ba615d3 100644 --- a/dlls/quartz/mtype.c +++ b/dlls/quartz/mtype.c @@ -11,7 +11,7 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" +#include "mmsystem.h" #include "strmif.h" #include "vfwmsgs.h" #include "uuids.h" @@ -119,6 +119,108 @@ BOOL QUARTZ_MediaSubType_IsFourCC( return IsEqualGUID( psubtype, &guidTemp ); } +HRESULT QUARTZ_MediaSubType_FromBitmap( + GUID* psubtype, const BITMAPINFOHEADER* pbi ) +{ + HRESULT hr; + DWORD* pdwBitf; + + if ( (pbi->biCompression & 0xffff) != 0 ) + return S_FALSE; + + if ( pbi->biWidth <= 0 || pbi->biHeight == 0 ) + return E_FAIL; + + hr = E_FAIL; + switch ( pbi->biCompression ) + { + case 0: + if ( pbi->biPlanes != 1 ) + break; + switch ( pbi->biBitCount ) + { + case 1: + memcpy( psubtype, &MEDIASUBTYPE_RGB1, sizeof(GUID) ); + hr = S_OK; + break; + case 4: + memcpy( psubtype, &MEDIASUBTYPE_RGB4, sizeof(GUID) ); + hr = S_OK; + break; + case 8: + memcpy( psubtype, &MEDIASUBTYPE_RGB8, sizeof(GUID) ); + hr = S_OK; + break; + case 16: + memcpy( psubtype, &MEDIASUBTYPE_RGB555, sizeof(GUID) ); + hr = S_OK; + break; + case 24: + memcpy( psubtype, &MEDIASUBTYPE_RGB24, sizeof(GUID) ); + hr = S_OK; + break; + case 32: + memcpy( psubtype, &MEDIASUBTYPE_RGB32, sizeof(GUID) ); + hr = S_OK; + break; + } + break; + case 1: + if ( pbi->biPlanes == 1 && pbi->biHeight > 0 && + pbi->biBitCount == 8 ) + { + QUARTZ_MediaSubType_FromFourCC( psubtype, mmioFOURCC('M','R','L','E') ); + hr = S_OK; + } + break; + case 2: + if ( pbi->biPlanes == 1 && pbi->biHeight > 0 && + pbi->biBitCount == 4 ) + { + QUARTZ_MediaSubType_FromFourCC( psubtype, mmioFOURCC('M','R','L','E') ); + hr = S_OK; + } + break; + case 3: + if ( pbi->biPlanes != 1 ) + break; + pdwBitf = (DWORD*)( (BYTE*)pbi + sizeof(BITMAPINFOHEADER) ); + switch ( pbi->biBitCount ) + { + case 16: + if ( pdwBitf[0] == 0x7c00 && + pdwBitf[1] == 0x03e0 && + pdwBitf[2] == 0x001f ) + { + memcpy( psubtype, &MEDIASUBTYPE_RGB555, sizeof(GUID) ); + hr = S_OK; + } + if ( pdwBitf[0] == 0xf800 && + pdwBitf[1] == 0x07e0 && + pdwBitf[2] == 0x001f ) + { + memcpy( psubtype, &MEDIASUBTYPE_RGB565, sizeof(GUID) ); + hr = S_OK; + } + break; + case 32: + if ( pdwBitf[0] == 0x00ff0000 && + pdwBitf[1] == 0x0000ff00 && + pdwBitf[2] == 0x000000ff ) + { + memcpy( psubtype, &MEDIASUBTYPE_RGB32, sizeof(GUID) ); + hr = S_OK; + } + break; + } + break; + } + + return hr; +} + + + /****************************************************************************/ typedef struct IEnumMediaTypesImpl diff --git a/dlls/quartz/mtype.h b/dlls/quartz/mtype.h index 9332f3ec5f7..d27958ef524 100644 --- a/dlls/quartz/mtype.h +++ b/dlls/quartz/mtype.h @@ -22,6 +22,9 @@ void QUARTZ_MediaSubType_FromFourCC( BOOL QUARTZ_MediaSubType_IsFourCC( const GUID* psubtype ); +HRESULT QUARTZ_MediaSubType_FromBitmap( + GUID* psubtype, const BITMAPINFOHEADER* pbi ); + HRESULT QUARTZ_CreateEnumMediaTypes( IEnumMediaTypes** ppobj, const AM_MEDIA_TYPE* pTypes, ULONG cTypes ); diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c index 897b31a1f23..d0e124aa22c 100644 --- a/dlls/quartz/parser.c +++ b/dlls/quartz/parser.c @@ -2,6 +2,8 @@ * Implements IBaseFilter for parsers. (internal) * * hidenori@a2.ctktv.ne.jp + * + * FIXME - save the array of pSample and handle errors/flushing correctly. */ #include "config.h" @@ -12,7 +14,6 @@ #include "winuser.h" #include "mmsystem.h" #include "winerror.h" -#include "wine/obj_base.h" #include "strmif.h" #include "vfwmsgs.h" #include "uuids.h" @@ -179,6 +180,8 @@ HRESULT CParserImpl_ProcessNextSample( CParserImpl* This ) hr = NOERROR; IMediaSample_Release(pSample); + TRACE("return %08lx\n",hr); + return hr; } @@ -232,6 +235,9 @@ DWORD WINAPI CParserImpl_ThreadEntry( LPVOID pv ) } continue; } + if ( This->m_ppOutPins[nIndex]->pin.pPinConnectedTo == NULL ) + continue; + rtSampleTimeStart = llReqStart * QUARTZ_TIMEUNITS; rtSampleTimeEnd = (llReqStart + lReqLength) * QUARTZ_TIMEUNITS; bReqNext = FALSE; diff --git a/dlls/quartz/parser.h b/dlls/quartz/parser.h index 1fb997c7cc3..45d4214c1c3 100644 --- a/dlls/quartz/parser.h +++ b/dlls/quartz/parser.h @@ -124,7 +124,6 @@ HRESULT QUARTZ_CreateParserOutPin( LPCWSTR pwszPinName ); -#define QUARTZ_TIMEUNITS ((LONGLONG)10000000) #define PARSER_POLL_INTERVAL 100 #define PARSER_RIFF_OfsFirst 12 @@ -136,6 +135,9 @@ HRESULT QUARTZ_CreateParserOutPin( #define PARSER_fact mmioFOURCC('f','a','c','t') #define PARSER_data mmioFOURCC('d','a','t','a') +#define PARSER_LIST mmioFOURCC('L','I','S','T') + +#define PARSER_hdrl mmioFOURCC('h','d','r','l') #define PARSER_avih mmioFOURCC('a','v','i','h') #define PARSER_strl mmioFOURCC('s','t','r','l') #define PARSER_strh mmioFOURCC('s','t','r','h') @@ -156,7 +158,22 @@ HRESULT QUARTZ_CreateParserOutPin( #define PARSER_BE_UINT32(ptr) (((DWORD)(ptr)[0]<<24)|((DWORD)(ptr)[1]<<16)|((DWORD)(ptr)[2]<<8)|((DWORD)(ptr)[3])) HRESULT QUARTZ_CreateWaveParser(IUnknown* punkOuter,void** ppobj); - +HRESULT QUARTZ_CreateAVISplitter(IUnknown* punkOuter,void** ppobj); + + +HRESULT RIFF_GetNext( + CParserImpl* pImpl, LONGLONG llOfs, + DWORD* pdwCode, DWORD* pdwLength ); +HRESULT RIFF_SearchChunk( + CParserImpl* pImpl, + DWORD dwSearchLengthMax, + LONGLONG llOfs, DWORD dwChunk, + LONGLONG* pllOfs, DWORD* pdwChunkLength ); +HRESULT RIFF_SearchList( + CParserImpl* pImpl, + DWORD dwSearchLengthMax, + LONGLONG llOfs, DWORD dwListChunk, + LONGLONG* pllOfs, DWORD* pdwChunkLength ); #endif /* WINE_DSHOW_PARSER_H */ diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index 5efb684429c..14a58c79126 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -9,5 +9,7 @@ void* QUARTZ_AllocMem( DWORD dwSize ); void QUARTZ_FreeMem( void* pMem ); void* QUARTZ_ReallocMem( void* pMem, DWORD dwSize ); +#define QUARTZ_TIMEUNITS ((LONGLONG)10000000) + #endif /* QUARTZ_PRIVATE_H */ diff --git a/dlls/quartz/regsvr.c b/dlls/quartz/regsvr.c index f979137f46d..01fb32780c6 100644 --- a/dlls/quartz/regsvr.c +++ b/dlls/quartz/regsvr.c @@ -13,7 +13,6 @@ #include "winerror.h" #include "winreg.h" #include "uuids.h" -#include "wine/unicode.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); @@ -46,7 +45,7 @@ const WCHAR QUARTZ_wszMerit[] = static void QUARTZ_CatPathSepW( WCHAR* pBuf ) { - int len = strlenW(pBuf); + int len = lstrlenW(pBuf); pBuf[len] = '\\'; pBuf[len+1] = 0; } @@ -96,7 +95,7 @@ LONG QUARTZ_RegSetValueString( return RegSetValueExW( hKey, lpszName, 0, REG_SZ, (const BYTE*)lpValue, - sizeof(lpValue[0]) * (strlenW(lpValue)+1) ); + sizeof(lpValue[0]) * (lstrlenW(lpValue)+1) ); } static @@ -124,16 +123,16 @@ HRESULT QUARTZ_CreateCLSIDPath( { int avail; - strcpyW( pwszBuf, QUARTZ_wszCLSID ); + lstrcpyW( pwszBuf, QUARTZ_wszCLSID ); QUARTZ_CatPathSepW( pwszBuf+5 ); QUARTZ_GUIDtoString( pwszBuf+6, pclsid ); if ( lpszPathFromCLSID != NULL ) { - avail = (int)dwBufLen - strlenW(pwszBuf) - 8; - if ( avail <= strlenW(lpszPathFromCLSID) ) + avail = (int)dwBufLen - lstrlenW(pwszBuf) - 8; + if ( avail <= lstrlenW(lpszPathFromCLSID) ) return E_FAIL; QUARTZ_CatPathSepW( pwszBuf ); - strcatW( pwszBuf, lpszPathFromCLSID ); + lstrcatW( pwszBuf, lpszPathFromCLSID ); } return NOERROR; @@ -245,9 +244,9 @@ HRESULT QUARTZ_RegisterCategory( WCHAR szCLSID[ 256 ]; QUARTZ_GUIDtoString( szCLSID, pguidFilterCategory ); - strcpyW( szFilterPath, QUARTZ_wszInstance ); + lstrcpyW( szFilterPath, QUARTZ_wszInstance ); QUARTZ_CatPathSepW( szFilterPath ); - strcatW( szFilterPath, szCLSID ); + lstrcatW( szFilterPath, szCLSID ); if ( fRegister ) { @@ -313,9 +312,9 @@ HRESULT QUARTZ_RegisterAMovieFilter( WCHAR szCLSID[ 256 ]; QUARTZ_GUIDtoString( szCLSID, pclsid ); - strcpyW( szFilterPath, QUARTZ_wszInstance ); + lstrcpyW( szFilterPath, QUARTZ_wszInstance ); QUARTZ_CatPathSepW( szFilterPath ); - strcatW( szFilterPath, ( lpInstance != NULL ) ? lpInstance : szCLSID ); + lstrcatW( szFilterPath, ( lpInstance != NULL ) ? lpInstance : szCLSID ); if ( fRegister ) { diff --git a/dlls/quartz/sample.c b/dlls/quartz/sample.c index 6b30408cb8c..c9c0e15ce4c 100644 --- a/dlls/quartz/sample.c +++ b/dlls/quartz/sample.c @@ -11,7 +11,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" #include "strmif.h" #include "vfwmsgs.h" diff --git a/dlls/quartz/seekpass.c b/dlls/quartz/seekpass.c index c8c45f6efb4..1c20f67cd04 100644 --- a/dlls/quartz/seekpass.c +++ b/dlls/quartz/seekpass.c @@ -13,7 +13,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" #include "strmif.h" #include "control.h" #include "uuids.h" diff --git a/dlls/quartz/sysclock.c b/dlls/quartz/sysclock.c index b2b64f78851..bef024a14cf 100644 --- a/dlls/quartz/sysclock.c +++ b/dlls/quartz/sysclock.c @@ -11,7 +11,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" #include "strmif.h" #include "uuids.h" diff --git a/dlls/quartz/vidren.c b/dlls/quartz/vidren.c index e30a076f733..47cade822f1 100644 --- a/dlls/quartz/vidren.c +++ b/dlls/quartz/vidren.c @@ -14,8 +14,6 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" -#include "wine/obj_base.h" -#include "wine/obj_oleaut.h" #include "mmsystem.h" #include "strmif.h" #include "control.h" diff --git a/dlls/quartz/wavparse.c b/dlls/quartz/wavparse.c index 6514e99c5af..49fbe2cb6db 100644 --- a/dlls/quartz/wavparse.c +++ b/dlls/quartz/wavparse.c @@ -11,8 +11,8 @@ #include "wingdi.h" #include "winuser.h" #include "mmsystem.h" +#include "mmreg.h" #include "winerror.h" -#include "wine/obj_base.h" #include "strmif.h" #include "vfwmsgs.h" #include "uuids.h" @@ -21,9 +21,7 @@ DEFAULT_DEBUG_CHANNEL(quartz); #include "quartz_private.h" - -/* for CLSID_quartzWaveParser. */ -#include "initguid.h" +#include "audioutl.h" #include "parser.h" @@ -63,29 +61,87 @@ HRESULT RIFF_GetNext( /* S_OK = found, S_FALSE = not found */ HRESULT RIFF_SearchChunk( CParserImpl* pImpl, + DWORD dwSearchLengthMax, LONGLONG llOfs, DWORD dwChunk, LONGLONG* pllOfs, DWORD* pdwChunkLength ) { HRESULT hr; DWORD dwCurCode; DWORD dwCurLen; + LONGLONG llCurLen; while ( 1 ) { hr = RIFF_GetNext( pImpl, llOfs, &dwCurCode, &dwCurLen ); if ( hr != S_OK ) break; + TRACE("%c%c%c%c len %lu\n", + (int)(dwCurCode>> 0)&0xff, + (int)(dwCurCode>> 8)&0xff, + (int)(dwCurCode>>16)&0xff, + (int)(dwCurCode>>24)&0xff, + (unsigned long)dwCurLen); if ( dwChunk == dwCurCode ) break; - llOfs += 8 + (LONGLONG)((dwCurLen+1)&(~1)); + llCurLen = 8 + (LONGLONG)((dwCurLen+1)&(~1)); + llOfs += llCurLen; + if ( (LONGLONG)dwSearchLengthMax <= llCurLen ) + return S_FALSE; + if ( dwSearchLengthMax != (DWORD)0xffffffff ) + dwSearchLengthMax -= (DWORD)llCurLen; } - *pllOfs = llOfs; + *pllOfs = llOfs + 8; *pdwChunkLength = dwCurLen; return hr; } +/* S_OK = found, S_FALSE = not found */ +HRESULT RIFF_SearchList( + CParserImpl* pImpl, + DWORD dwSearchLengthMax, + LONGLONG llOfs, DWORD dwListChunk, + LONGLONG* pllOfs, DWORD* pdwChunkLength ) +{ + HRESULT hr; + DWORD dwCurLen; + LONGLONG llCurLen; + BYTE bTemp[4]; + + while ( 1 ) + { + hr = RIFF_SearchChunk( + pImpl, dwSearchLengthMax, + llOfs, PARSER_LIST, + &llOfs, &dwCurLen ); + if ( hr != S_OK ) + break; + + hr = IAsyncReader_SyncRead( pImpl->m_pReader, llOfs, 4, bTemp ); + if ( hr != S_OK ) + break; + + if ( mmioFOURCC(bTemp[0],bTemp[1],bTemp[2],bTemp[3]) == dwListChunk ) + break; + + llCurLen = (LONGLONG)((dwCurLen+1)&(~1)); + llOfs += llCurLen; + if ( (LONGLONG)dwSearchLengthMax <= (llCurLen+8) ) + return S_FALSE; + if ( dwSearchLengthMax != (DWORD)0xffffffff ) + dwSearchLengthMax -= (DWORD)(llCurLen+8); + } + + if ( dwCurLen < 12 ) + return E_FAIL; + + *pllOfs = llOfs+4; + *pdwChunkLength = dwCurLen-4; + + return hr; +} + @@ -122,13 +178,13 @@ static HRESULT CWavParseImpl_InitWAV( CParserImpl* pImpl, CWavParseImpl* This ) DWORD dwChunkLength; hr = RIFF_SearchChunk( - pImpl, PARSER_RIFF_OfsFirst, - PARSER_fmt, &llOfs, &dwChunkLength ); + pImpl, (DWORD)0xffffffff, + PARSER_RIFF_OfsFirst, PARSER_fmt, + &llOfs, &dwChunkLength ); if ( FAILED(hr) ) return hr; if ( hr != S_OK || ( dwChunkLength < (sizeof(WAVEFORMATEX)-2) ) ) return E_FAIL; - llOfs += 8; This->cbFmt = dwChunkLength; if ( dwChunkLength < sizeof(WAVEFORMATEX) ) @@ -149,8 +205,9 @@ static HRESULT CWavParseImpl_InitWAV( CParserImpl* pImpl, CWavParseImpl* This ) hr = RIFF_SearchChunk( - pImpl, PARSER_RIFF_OfsFirst, - PARSER_data, &llOfs, &dwChunkLength ); + pImpl, (DWORD)0xffffffff, + PARSER_RIFF_OfsFirst, PARSER_data, + &llOfs, &dwChunkLength ); if ( FAILED(hr) ) return hr; if ( hr != S_OK || dwChunkLength == 0 ) @@ -195,18 +252,18 @@ static HRESULT CWavParseImpl_InitAU( CParserImpl* pImpl, CWavParseImpl* This ) switch ( datafmt ) { case 1: - wfx.wFormatTag = 7; + wfx.wFormatTag = WAVE_FORMAT_MULAW; wfx.nBlockAlign = datachannels; wfx.wBitsPerSample = 8; break; case 2: - wfx.wFormatTag = 1; + wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nBlockAlign = datachannels; wfx.wBitsPerSample = 8; This->iFmtType = WaveParse_Signed8; break; case 3: - wfx.wFormatTag = 1; + wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nBlockAlign = datachannels; wfx.wBitsPerSample = 16; This->iFmtType = WaveParse_Signed16BE; @@ -417,13 +474,36 @@ static HRESULT CWavParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStream static HRESULT CWavParseImpl_ProcessSample( CParserImpl* pImpl, ULONG nStreamIndex, LONGLONG llStart, LONG lLength, IMediaSample* pSample ) { CWavParseImpl* This = (CWavParseImpl*)pImpl->m_pUserData; + BYTE* pData; + LONG lActLen; + HRESULT hr; TRACE("(%p)\n",This); + hr = IMediaSample_GetPointer(pSample,&pData); + if ( FAILED(hr) ) + return hr; + lActLen = (LONG)IMediaSample_GetActualDataLength(pSample); + if ( lActLen != lLength ) + return E_FAIL; + switch ( This->iFmtType ) { case WaveParse_Native: break; + case WaveParse_Signed8: + AUDIOUTL_ChangeSign8(pData,lActLen); + break; + case WaveParse_Signed16BE: + AUDIOUTL_ByteSwap(pData,lActLen); + break; + case WaveParse_Unsigned16LE: + AUDIOUTL_ChangeSign16LE(pData,lActLen); + break; + case WaveParse_Unsigned16BE: + AUDIOUTL_ChangeSign16BE(pData,lActLen); + AUDIOUTL_ByteSwap(pData,lActLen); + break; default: FIXME("(%p) - %d not implemented\n", This, This->iFmtType ); return E_FAIL; diff --git a/include/amvideo.h b/include/amvideo.h index 19dabb6f607..50cd4389d0a 100644 --- a/include/amvideo.h +++ b/include/amvideo.h @@ -1,7 +1,6 @@ #ifndef __WINE_AMVIDEO_H_ #define __WINE_AMVIDEO_H_ -#include "ole2.h" #include "ddraw.h" diff --git a/include/control.h b/include/control.h index a5c9c43e4a7..c1675d1c211 100644 --- a/include/control.h +++ b/include/control.h @@ -1,8 +1,6 @@ #ifndef __WINE_CONTROL_H_ #define __WINE_CONTROL_H_ -#include "ole2.h" - /* forward decls. */ typedef struct IAMCollection IAMCollection; diff --git a/include/strmif.h b/include/strmif.h index 9176e66efb0..0186206df71 100644 --- a/include/strmif.h +++ b/include/strmif.h @@ -10,7 +10,10 @@ #ifndef __WINE_STRMIF_H_ #define __WINE_STRMIF_H_ -#include "ole2.h" +#include "wine/obj_base.h" +#include "wine/obj_misc.h" +#include "wine/obj_storage.h" +#include "wine/obj_moniker.h" #include "wine/obj_oleaut.h" #include "wine/obj_property.h" #include "wine/obj_ksproperty.h" -- 2.11.4.GIT