2 * Implements IBaseFilter for parsers. (internal)
4 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * FIXME - handle errors/flushing correctly.
21 * FIXME - handle seeking.
38 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
41 #include "quartz_private.h"
46 #define QUARTZ_MSG_EXITTHREAD (WM_APP+2)
47 #define QUARTZ_MSG_SEEK (WM_APP+3)
54 HRESULT CParserOutPinImpl_InitIMediaSeeking( CParserOutPinImpl* This );
55 void CParserOutPinImpl_UninitIMediaSeeking( CParserOutPinImpl* This );
56 HRESULT CParserOutPinImpl_InitIMediaPosition( CParserOutPinImpl* This );
57 void CParserOutPinImpl_UninitIMediaPosition( CParserOutPinImpl* This );
59 /***************************************************************************
61 * CParserImpl internal thread
66 void CParserImplThread_ClearAllRequests( CParserImpl* This )
72 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
74 This->m_ppOutPins[nIndex]->m_bReqUsed = FALSE;
75 This->m_ppOutPins[nIndex]->m_pReqSample = NULL;
80 void CParserImplThread_ReleaseAllRequests( CParserImpl* This )
86 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
88 if ( This->m_ppOutPins[nIndex]->m_bReqUsed )
90 if ( This->m_ppOutPins[nIndex]->m_pReqSample != NULL )
92 IMediaSample_Release(This->m_ppOutPins[nIndex]->m_pReqSample);
93 This->m_ppOutPins[nIndex]->m_pReqSample = NULL;
95 This->m_ppOutPins[nIndex]->m_bReqUsed = FALSE;
101 BOOL CParserImplThread_HasPendingSamples( CParserImpl* This )
105 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
107 if ( This->m_ppOutPins[nIndex]->m_bReqUsed &&
108 This->m_ppOutPins[nIndex]->m_pReqSample != NULL )
116 HRESULT CParserImplThread_FlushAllPendingSamples( CParserImpl* This )
119 IMediaSample* pSample;
122 TRACE("(%p)\n",This);
124 /* remove all samples from queue. */
125 hr = IAsyncReader_BeginFlush(This->m_pReader);
128 IAsyncReader_EndFlush(This->m_pReader);
130 /* remove all processed samples from queue. */
133 hr = IAsyncReader_WaitForNext(This->m_pReader,0,&pSample,&dwContext);
138 CParserImplThread_ReleaseAllRequests(This);
143 static HRESULT CParserImplThread_SendEndOfStream( CParserImpl* This )
148 CParserOutPinImpl* pOutPin;
150 TRACE("(%p)\n",This);
151 if ( This->m_bSendEOS )
153 This->m_bSendEOS = TRUE;
156 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
158 pOutPin = This->m_ppOutPins[nIndex];
159 hr = CPinBaseImpl_SendEndOfStream(&pOutPin->pin);
162 if ( SUCCEEDED(hrRet) )
167 if ( hr != S_OK && hrRet == S_OK )
175 static HRESULT CParserImplThread_SendFlush( CParserImpl* This )
180 CParserOutPinImpl* pOutPin;
182 TRACE("(%p)\n",This);
184 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
186 pOutPin = This->m_ppOutPins[nIndex];
187 hr = CPinBaseImpl_SendBeginFlush(&pOutPin->pin);
190 if ( SUCCEEDED(hrRet) )
195 if ( hr != S_OK && hrRet == S_OK )
197 hr = CPinBaseImpl_SendEndFlush(&pOutPin->pin);
206 static void CParserImplThread_ErrorAbort( CParserImpl* This, HRESULT hr )
208 CBaseFilterImpl_MediaEventNotify(
209 &This->basefilter,EC_ERRORABORT,(LONG_PTR)hr,(LONG_PTR)0);
210 CParserImplThread_SendEndOfStream(This);
214 HRESULT CParserImplThread_ProcessNextSample( CParserImpl* This )
216 IMediaSample* pSample;
220 CParserOutPinImpl* pOutPin;
225 if ( PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_REMOVE ) )
228 switch ( msg.message )
230 case QUARTZ_MSG_EXITTHREAD:
231 TRACE("(%p) EndThread\n",This);
232 CParserImplThread_FlushAllPendingSamples(This);
233 CParserImplThread_ClearAllRequests(This);
234 CParserImplThread_SendFlush(This);
235 CParserImplThread_SendEndOfStream(This);
236 TRACE("(%p) exit thread\n",This);
238 case QUARTZ_MSG_SEEK:
239 FIXME("(%p) Seek\n",This);
240 CParserImplThread_FlushAllPendingSamples(This);
241 hr = CParserImplThread_SendFlush(This);
242 CParserImplThread_SendEndOfStream(This);
243 /* FIXME - process seeking. */
244 /* FIXME - Send NewSegment. */
247 FIXME( "invalid message %04u\n", (unsigned)msg.message );
249 CParserImplThread_ErrorAbort(This,hr);
255 hr = IAsyncReader_WaitForNext(This->m_pReader,PARSER_POLL_INTERVAL,&pSample,&dwContext);
256 nIndex = (ULONG)dwContext;
257 if ( hr != VFW_E_TIMEOUT )
262 CParserImplThread_ErrorAbort(This,hr);
266 pOutPin = This->m_ppOutPins[nIndex];
267 if ( pOutPin != NULL && pOutPin->m_bReqUsed )
269 if ( This->m_pHandler->pProcessSample != NULL )
270 hr = This->m_pHandler->pProcessSample(This,nIndex,pOutPin->m_llReqStart,pOutPin->m_lReqLength,pOutPin->m_pReqSample);
272 IMediaSample_SetSyncPoint( pOutPin->m_pReqSample, (pOutPin->m_dwSampleFlags & AM_SAMPLE_SPLICEPOINT) ? TRUE : FALSE );
273 IMediaSample_SetPreroll( pOutPin->m_pReqSample, (pOutPin->m_dwSampleFlags & AM_SAMPLE_PREROLL) ? TRUE : FALSE );
274 IMediaSample_SetDiscontinuity( pOutPin->m_pReqSample, (pOutPin->m_dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) ? TRUE : FALSE );
278 if ( pOutPin->m_pOutPinAllocator != NULL &&
279 pOutPin->m_pOutPinAllocator != This->m_pAllocator )
281 /* if pin has its own allocator, sample must be copied */
282 hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 );
285 hr = QUARTZ_IMediaSample_Copy(
286 pSample, pOutPin->m_pReqSample, TRUE );
288 hr = CPinBaseImpl_SendSample(&pOutPin->pin,pSample);
289 IMediaSample_Release(pSample);
294 hr = CPinBaseImpl_SendSample(&pOutPin->pin,pOutPin->m_pReqSample);
299 CParserImplThread_ErrorAbort(This,hr);
301 IMediaSample_Release(pOutPin->m_pReqSample);
302 pOutPin->m_pReqSample = NULL;
303 pOutPin->m_bReqUsed = FALSE;
309 TRACE("return %08lx\n",hr);
315 DWORD WINAPI CParserImplThread_Entry( LPVOID pv )
317 CParserImpl* This = (CParserImpl*)pv;
321 REFERENCE_TIME rtSampleTimeStart, rtSampleTimeEnd;
325 REFERENCE_TIME rtReqStart, rtReqStop;
326 IMediaSample* pSample;
329 /* initialize the message queue. */
330 PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE );
332 CParserImplThread_ClearAllRequests(This);
334 /* resume the owner thread. */
335 SetEvent( This->m_hEventInit );
337 TRACE( "Enter message loop.\n" );
344 /* Get the next request. */
345 hr = This->m_pHandler->pGetNextRequest( This, &nIndex, &llReqStart, &lReqLength, &rtReqStart, &rtReqStop, &dwSampleFlags );
348 CParserImplThread_ErrorAbort(This,hr);
353 /* Flush pending samples. */
355 while ( CParserImplThread_HasPendingSamples(This) )
357 hr = CParserImplThread_ProcessNextSample(This);
363 /* notification is already sent */
367 /* Send End Of Stream. */
368 hr = CParserImplThread_SendEndOfStream(This);
371 /* notification is already sent */
376 hr = CParserImplThread_ProcessNextSample(This);
379 /* notification is already sent */
384 if ( This->m_ppOutPins[nIndex]->pin.pPinConnectedTo == NULL )
387 rtSampleTimeStart = This->basefilter.rtStart + llReqStart * QUARTZ_TIMEUNITS;
388 rtSampleTimeEnd = (llReqStart + lReqLength) * QUARTZ_TIMEUNITS;
392 if ( !This->m_ppOutPins[nIndex]->m_bReqUsed )
394 hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 );
397 CParserImplThread_ErrorAbort(This,hr);
400 hr = IMediaSample_SetTime(pSample,&rtSampleTimeStart,&rtSampleTimeEnd);
402 hr = IAsyncReader_Request(This->m_pReader,pSample,nIndex);
405 CParserImplThread_ErrorAbort(This,hr);
409 This->m_ppOutPins[nIndex]->m_bReqUsed = TRUE;
410 This->m_ppOutPins[nIndex]->m_pReqSample = pSample;
411 This->m_ppOutPins[nIndex]->m_llReqStart = llReqStart;
412 This->m_ppOutPins[nIndex]->m_lReqLength = lReqLength;
413 This->m_ppOutPins[nIndex]->m_rtReqStart = rtSampleTimeStart;
414 This->m_ppOutPins[nIndex]->m_rtReqStop = rtSampleTimeEnd;
415 This->m_ppOutPins[nIndex]->m_dwSampleFlags = dwSampleFlags;
420 hr = CParserImplThread_ProcessNextSample(This);
423 /* notification is already sent */
431 /***************************************************************************
433 * CParserImpl internal methods
438 void CParserImpl_SetAsyncReader( CParserImpl* This, IAsyncReader* pReader )
440 if ( This->m_pReader != NULL )
442 IAsyncReader_Release( This->m_pReader );
443 This->m_pReader = NULL;
445 if ( pReader != NULL )
447 This->m_pReader = pReader;
448 IAsyncReader_AddRef(This->m_pReader);
453 void CParserImpl_ReleaseOutPins( CParserImpl* This )
457 if ( This->m_ppOutPins != NULL )
459 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
461 if ( This->m_ppOutPins[nIndex] != NULL )
463 IUnknown_Release(This->m_ppOutPins[nIndex]->unk.punkControl);
464 This->m_ppOutPins[nIndex] = NULL;
467 QUARTZ_FreeMem(This->m_ppOutPins);
468 This->m_ppOutPins = NULL;
470 This->m_cOutStreams = 0;
474 BOOL CParserImpl_OutPinsAreConnected( CParserImpl* This )
476 QUARTZ_CompListItem* pItem;
481 QUARTZ_CompList_Lock( This->basefilter.pOutPins );
482 pItem = QUARTZ_CompList_GetFirst( This->basefilter.pOutPins );
483 while ( pItem != NULL )
487 pPin = (IPin*)QUARTZ_CompList_GetItemPtr(pItem);
489 hr = IPin_ConnectedTo(pPin,&pPinPeer);
490 if ( hr == S_OK && pPinPeer != NULL )
492 IPin_Release(pPinPeer);
495 pItem = QUARTZ_CompList_GetNext( This->basefilter.pOutPins, pItem );
497 QUARTZ_CompList_Unlock( This->basefilter.pOutPins );
503 void CParserImpl_ReleaseListOfOutPins( CParserImpl* This )
505 QUARTZ_CompListItem* pItem;
507 QUARTZ_CompList_Lock( This->basefilter.pOutPins );
510 pItem = QUARTZ_CompList_GetFirst( This->basefilter.pOutPins );
513 QUARTZ_CompList_RemoveComp(
514 This->basefilter.pOutPins,
515 QUARTZ_CompList_GetItemPtr(pItem) );
517 QUARTZ_CompList_Unlock( This->basefilter.pOutPins );
522 HRESULT CParserImpl_BeginThread( CParserImpl* This )
527 if ( This->m_hEventInit != (HANDLE)NULL &&
528 This->m_hThread != (HANDLE)NULL )
531 This->m_hEventInit = CreateEventA(NULL,TRUE,FALSE,NULL);
532 if ( This->m_hEventInit == (HANDLE)NULL )
533 return E_OUTOFMEMORY;
535 /* create the processing thread. */
536 This->m_hThread = CreateThread(
538 CParserImplThread_Entry,
540 0, &This->m_dwThreadId );
541 if ( This->m_hThread == (HANDLE)NULL )
544 hEvents[0] = This->m_hEventInit;
545 hEvents[1] = This->m_hThread;
547 dwRes = WaitForMultipleObjects(2,hEvents,FALSE,INFINITE);
548 if ( dwRes != WAIT_OBJECT_0 )
555 void CParserImpl_EndThread( CParserImpl* This )
557 TRACE("(%p)\n",This);
558 if ( This->m_hThread != (HANDLE)NULL )
560 if ( PostThreadMessageA(
561 This->m_dwThreadId, QUARTZ_MSG_EXITTHREAD, 0, 0 ) )
563 WaitForSingleObject( This->m_hThread, INFINITE );
565 CloseHandle( This->m_hThread );
566 This->m_hThread = (HANDLE)NULL;
567 This->m_dwThreadId = 0;
569 if ( This->m_hEventInit != (HANDLE)NULL )
571 CloseHandle( This->m_hEventInit );
572 This->m_hEventInit = (HANDLE)NULL;
577 HRESULT CParserImpl_MemCommit( CParserImpl* This )
581 IMemAllocator* pAlloc;
583 TRACE("(%p)\n",This);
585 if ( This->m_pAllocator == NULL )
588 hr = IMemAllocator_Commit( This->m_pAllocator );
592 if ( This->m_ppOutPins != NULL && This->m_cOutStreams > 0 )
594 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
596 pAlloc = This->m_ppOutPins[nIndex]->m_pOutPinAllocator;
597 if ( pAlloc != NULL && pAlloc != This->m_pAllocator )
599 hr = IMemAllocator_Commit( pAlloc );
610 void CParserImpl_MemDecommit( CParserImpl* This )
613 IMemAllocator* pAlloc;
615 TRACE("(%p)\n",This);
617 if ( This->m_pAllocator != NULL )
618 IMemAllocator_Decommit( This->m_pAllocator );
620 if ( This->m_ppOutPins != NULL && This->m_cOutStreams > 0 )
622 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
624 pAlloc = This->m_ppOutPins[nIndex]->m_pOutPinAllocator;
625 if ( pAlloc != NULL )
626 IMemAllocator_Decommit( pAlloc );
632 HRESULT CParserImpl_GetPreferredTimeFormat( CParserImpl* This, GUID* pguidFormat )
634 static const GUID* tryformats[] =
636 &TIME_FORMAT_MEDIA_TIME,
645 if ( This->m_pHandler->pIsTimeFormatSupported == NULL )
649 while ( tryformats[n] != NULL )
651 if ( This->m_pHandler->pIsTimeFormatSupported( This, tryformats[n] ) == S_OK )
653 memcpy( pguidFormat, tryformats[n], sizeof(GUID) );
664 /***************************************************************************
666 * CParserImpl methods
670 static HRESULT CParserImpl_OnActive( CBaseFilterImpl* pImpl )
672 CParserImpl_THIS(pImpl,basefilter);
674 TRACE( "(%p)\n", This );
676 if ( !CParserImpl_OutPinsAreConnected(This) )
682 static HRESULT CParserImpl_OnInactive( CBaseFilterImpl* pImpl )
684 CParserImpl_THIS(pImpl,basefilter);
687 TRACE( "(%p)\n", This );
689 if ( !CParserImpl_OutPinsAreConnected(This) )
692 hr = CParserImpl_MemCommit(This);
695 hr = CParserImpl_BeginThread(This);
698 CParserImpl_EndThread(This);
705 static HRESULT CParserImpl_OnStop( CBaseFilterImpl* pImpl )
707 CParserImpl_THIS(pImpl,basefilter);
710 FIXME( "(%p)\n", This );
712 CParserImpl_EndThread(This);
713 CParserImpl_MemDecommit(This);
714 This->m_bSendEOS = FALSE;
717 if ( This->m_pHandler->pSetCurPos != NULL )
719 for ( n = 0; n < This->m_cOutStreams; n++ )
720 This->m_pHandler->pSetCurPos(This,&This->m_guidTimeFormat,n,(LONGLONG)0);
727 static const CBaseFilterHandlers filterhandlers =
729 CParserImpl_OnActive, /* pOnActive */
730 CParserImpl_OnInactive, /* pOnInactive */
731 CParserImpl_OnStop, /* pOnStop */
735 /***************************************************************************
737 * CParserInPinImpl methods
741 static HRESULT CParserInPinImpl_OnPreConnect( CPinBaseImpl* pImpl, IPin* pPin )
743 CParserInPinImpl_THIS(pImpl,pin);
747 IAsyncReader* pReader = NULL;
748 LPCWSTR pwszOutPinName;
749 IMemAllocator* pAllocActual;
752 TRACE("(%p,%p)\n",This,pPin);
754 if ( This->pParser->m_pHandler->pInitParser == NULL ||
755 This->pParser->m_pHandler->pUninitParser == NULL ||
756 This->pParser->m_pHandler->pGetOutPinName == NULL ||
757 This->pParser->m_pHandler->pGetStreamType == NULL ||
758 This->pParser->m_pHandler->pCheckStreamType == NULL ||
759 This->pParser->m_pHandler->pGetAllocProp == NULL ||
760 This->pParser->m_pHandler->pGetNextRequest == NULL )
762 FIXME("this parser is not implemented.\n");
766 /* at first, release all output pins. */
767 if ( CParserImpl_OutPinsAreConnected(This->pParser) )
769 CParserImpl_ReleaseListOfOutPins(This->pParser);
770 CParserImpl_ReleaseOutPins(This->pParser);
772 CParserImpl_SetAsyncReader( This->pParser, NULL );
773 hr = IPin_QueryInterface( pPin, &IID_IAsyncReader, (void**)&pReader );
776 CParserImpl_SetAsyncReader( This->pParser, pReader );
777 IAsyncReader_Release(pReader);
779 /* initialize parser. */
780 hr = This->pParser->m_pHandler->pInitParser(This->pParser,&This->pParser->m_cOutStreams);
783 This->pParser->m_ppOutPins = (CParserOutPinImpl**)QUARTZ_AllocMem(
784 sizeof(CParserOutPinImpl*) * This->pParser->m_cOutStreams );
785 if ( This->pParser->m_ppOutPins == NULL )
786 return E_OUTOFMEMORY;
787 for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
788 This->pParser->m_ppOutPins[nIndex] = NULL;
790 /* create and initialize an allocator. */
791 hr = This->pParser->m_pHandler->pGetAllocProp(This->pParser,&This->pParser->m_propAlloc);
794 if ( This->pParser->m_propAlloc.cbAlign == 0 )
795 This->pParser->m_propAlloc.cbAlign = 1;
797 if ( This->pParser->m_pAllocator == NULL )
799 hr = QUARTZ_CreateMemoryAllocator(NULL,(void**)&punk);
802 hr = IUnknown_QueryInterface( punk, &IID_IMemAllocator, (void**)&This->pParser->m_pAllocator );
803 IUnknown_Release(punk);
808 hr = IAsyncReader_RequestAllocator(pReader,This->pParser->m_pAllocator,&This->pParser->m_propAlloc,&pAllocActual);
811 IMemAllocator_Release(This->pParser->m_pAllocator);
812 This->pParser->m_pAllocator = pAllocActual;
814 /* create output pins. */
815 for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
817 pwszOutPinName = This->pParser->m_pHandler->pGetOutPinName(This->pParser,nIndex);
818 if ( pwszOutPinName == NULL )
820 hr = QUARTZ_CreateParserOutPin(
822 &This->pParser->m_csParser,
823 &This->pParser->m_ppOutPins[nIndex],
824 nIndex, pwszOutPinName );
826 hr = QUARTZ_CompList_AddTailComp(
827 This->pParser->basefilter.pOutPins,
828 (IUnknown*)&(This->pParser->m_ppOutPins[nIndex]->pin),
832 pmt = &This->pParser->m_ppOutPins[nIndex]->m_mtOut;
833 QUARTZ_MediaType_Free( pmt );
834 ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
835 hr = This->pParser->m_pHandler->pGetStreamType(This->pParser,nIndex,pmt);
838 ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
841 This->pParser->m_ppOutPins[nIndex]->pin.cAcceptTypes = 1;
842 This->pParser->m_ppOutPins[nIndex]->pin.pmtAcceptTypes = pmt;
848 static HRESULT CParserInPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
850 CParserInPinImpl_THIS(pImpl,pin);
852 CParserImpl_OnInactive(&This->pParser->basefilter);
853 CParserImpl_OnStop(&This->pParser->basefilter);
854 if ( This->pParser->m_pHandler->pUninitParser != NULL )
855 This->pParser->m_pHandler->pUninitParser(This->pParser);
856 CParserImpl_SetAsyncReader( This->pParser, NULL );
857 if ( This->pParser->m_pAllocator != NULL )
859 IMemAllocator_Decommit(This->pParser->m_pAllocator);
860 IMemAllocator_Release(This->pParser->m_pAllocator);
861 This->pParser->m_pAllocator = NULL;
867 static HRESULT CParserInPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
869 CParserInPinImpl_THIS(pImpl,pin);
871 TRACE("(%p,%p)\n",This,pmt);
873 if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Stream ) )
879 static const CBasePinHandlers inputpinhandlers =
881 CParserInPinImpl_OnPreConnect, /* pOnPreConnect */
882 NULL, /* pOnPostConnect */
883 CParserInPinImpl_OnDisconnect, /* pOnDisconnect */
884 CParserInPinImpl_CheckMediaType, /* pCheckMediaType */
885 NULL, /* pQualityNotify */
887 NULL, /* pReceiveCanBlock */
888 NULL, /* pEndOfStream */
889 NULL, /* pBeginFlush */
890 NULL, /* pEndFlush */
891 NULL, /* pNewSegment */
894 /***************************************************************************
896 * CParserOutPinImpl methods
900 static HRESULT CParserOutPinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPin )
902 CParserOutPinImpl_THIS(pImpl,pin);
903 ALLOCATOR_PROPERTIES propReq;
904 ALLOCATOR_PROPERTIES propActual;
905 IMemAllocator* pAllocator;
907 BOOL bNewAllocator = FALSE;
909 TRACE("(%p,%p)\n",This,pPin);
911 if ( This->pin.pMemInputPinConnectedTo == NULL )
914 if ( This->m_pOutPinAllocator != NULL )
916 IMemAllocator_Release(This->m_pOutPinAllocator);
917 This->m_pOutPinAllocator = NULL;
920 /* try to use This->pParser->m_pAllocator. */
921 ZeroMemory( &propReq, sizeof(ALLOCATOR_PROPERTIES) );
922 hr = IMemInputPin_GetAllocatorRequirements(
923 This->pin.pMemInputPinConnectedTo, &propReq );
924 if ( propReq.cbAlign != 0 )
926 if ( This->pParser->m_propAlloc.cbAlign != ( This->pParser->m_propAlloc.cbAlign / propReq.cbAlign * propReq.cbAlign ) )
927 bNewAllocator = TRUE;
929 if ( propReq.cbPrefix != 0 )
930 bNewAllocator = TRUE;
931 if ( !bNewAllocator )
933 hr = IMemInputPin_NotifyAllocator(
934 This->pin.pMemInputPinConnectedTo,
935 This->pParser->m_pAllocator, FALSE );
938 This->m_pOutPinAllocator = This->pParser->m_pAllocator;
939 IMemAllocator_AddRef(This->m_pOutPinAllocator);
944 hr = IMemInputPin_GetAllocator(
945 This->pin.pMemInputPinConnectedTo, &pAllocator );
948 hr = IMemAllocator_SetProperties( pAllocator, &This->pParser->m_propAlloc, &propActual );
950 hr = IMemInputPin_NotifyAllocator(
951 This->pin.pMemInputPinConnectedTo, pAllocator, FALSE );
954 IMemAllocator_Release(pAllocator);
958 This->m_pOutPinAllocator = pAllocator;
962 static HRESULT CParserOutPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
964 CParserOutPinImpl_THIS(pImpl,pin);
966 if ( This->m_pOutPinAllocator != NULL )
968 IMemAllocator_Release(This->m_pOutPinAllocator);
969 This->m_pOutPinAllocator = NULL;
975 static HRESULT CParserOutPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
977 CParserOutPinImpl_THIS(pImpl,pin);
980 TRACE("(%p,%p)\n",This,pmt);
984 if ( This->pParser->m_pHandler->pCheckStreamType == NULL )
987 hr = This->pParser->m_pHandler->pCheckStreamType( This->pParser, This->nStreamIndex, pmt );
995 static const CBasePinHandlers outputpinhandlers =
997 NULL, /* pOnPreConnect */
998 CParserOutPinImpl_OnPostConnect, /* pOnPostConnect */
999 CParserOutPinImpl_OnDisconnect, /* pOnDisconnect */
1000 CParserOutPinImpl_CheckMediaType, /* pCheckMediaType */
1001 NULL, /* pQualityNotify */
1002 OutputPinSync_Receive, /* pReceive */
1003 OutputPinSync_ReceiveCanBlock, /* pReceiveCanBlock */
1004 OutputPinSync_EndOfStream, /* pEndOfStream */
1005 OutputPinSync_BeginFlush, /* pBeginFlush */
1006 OutputPinSync_EndFlush, /* pEndFlush */
1007 OutputPinSync_NewSegment, /* pNewSegment */
1010 /***************************************************************************
1012 * new/delete CParserImpl
1016 /* can I use offsetof safely? - FIXME? */
1017 static QUARTZ_IFEntry FilterIFEntries[] =
1019 { &IID_IPersist, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1020 { &IID_IMediaFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1021 { &IID_IBaseFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1024 static void QUARTZ_DestroyParser(IUnknown* punk)
1026 CParserImpl_THIS(punk,unk);
1028 TRACE( "(%p)\n", This );
1030 if ( This->m_pInPin != NULL )
1031 CParserInPinImpl_OnDisconnect(&This->m_pInPin->pin);
1033 CParserImpl_SetAsyncReader( This, NULL );
1034 if ( This->m_pAllocator != NULL )
1036 IMemAllocator_Release(This->m_pAllocator);
1037 This->m_pAllocator = NULL;
1039 if ( This->m_pInPin != NULL )
1041 IUnknown_Release(This->m_pInPin->unk.punkControl);
1042 This->m_pInPin = NULL;
1044 CParserImpl_ReleaseOutPins( This );
1046 DeleteCriticalSection( &This->m_csParser );
1048 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
1051 HRESULT QUARTZ_CreateParser(
1052 IUnknown* punkOuter,void** ppobj,
1053 const CLSID* pclsidParser,
1054 LPCWSTR pwszParserName,
1055 LPCWSTR pwszInPinName,
1056 const ParserHandlers* pHandler )
1058 CParserImpl* This = NULL;
1061 TRACE("(%p,%p)\n",punkOuter,ppobj);
1063 This = (CParserImpl*)
1064 QUARTZ_AllocObj( sizeof(CParserImpl) );
1066 return E_OUTOFMEMORY;
1067 ZeroMemory( This, sizeof(CParserImpl) );
1069 This->m_pInPin = NULL;
1070 This->m_cOutStreams = 0;
1071 This->m_ppOutPins = NULL;
1072 memcpy( &This->m_guidTimeFormat, &TIME_FORMAT_NONE, sizeof(GUID) );
1073 This->m_pReader = NULL;
1074 This->m_pAllocator = NULL;
1075 ZeroMemory( &This->m_propAlloc, sizeof(ALLOCATOR_PROPERTIES) );
1076 This->m_hEventInit = (HANDLE)NULL;
1077 This->m_hThread = (HANDLE)NULL;
1078 This->m_dwThreadId = 0;
1079 This->m_bSendEOS = FALSE;
1080 This->m_pHandler = pHandler;
1081 This->m_pUserData = NULL;
1083 QUARTZ_IUnkInit( &This->unk, punkOuter );
1085 hr = CBaseFilterImpl_InitIBaseFilter(
1087 This->unk.punkControl,
1091 if ( SUCCEEDED(hr) )
1093 /* construct this class. */
1098 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
1104 QUARTZ_FreeObj(This);
1108 This->unk.pEntries = FilterIFEntries;
1109 This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
1110 This->unk.pOnFinalRelease = QUARTZ_DestroyParser;
1111 InitializeCriticalSection( &This->m_csParser );
1113 /* create the input pin. */
1114 hr = QUARTZ_CreateParserInPin(
1119 if ( SUCCEEDED(hr) )
1120 hr = QUARTZ_CompList_AddComp(
1121 This->basefilter.pInPins,
1122 (IUnknown*)&(This->m_pInPin->pin),
1127 IUnknown_Release( This->unk.punkControl );
1131 *ppobj = (void*)&(This->unk);
1133 (void)CParserImpl_GetPreferredTimeFormat( This, &This->m_guidTimeFormat );
1138 /***************************************************************************
1140 * new/delete CParserInPinImpl
1144 /* can I use offsetof safely? - FIXME? */
1145 static QUARTZ_IFEntry InPinIFEntries[] =
1147 { &IID_IPin, offsetof(CParserInPinImpl,pin)-offsetof(CParserInPinImpl,unk) },
1148 { &IID_IMemInputPin, offsetof(CParserInPinImpl,meminput)-offsetof(CParserInPinImpl,unk) },
1151 static void QUARTZ_DestroyParserInPin(IUnknown* punk)
1153 CParserInPinImpl_THIS(punk,unk);
1155 TRACE( "(%p)\n", This );
1157 CPinBaseImpl_UninitIPin( &This->pin );
1158 CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
1161 HRESULT QUARTZ_CreateParserInPin(
1162 CParserImpl* pFilter,
1163 CRITICAL_SECTION* pcsPin,
1164 CParserInPinImpl** ppPin,
1165 LPCWSTR pwszPinName )
1167 CParserInPinImpl* This = NULL;
1170 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
1172 This = (CParserInPinImpl*)
1173 QUARTZ_AllocObj( sizeof(CParserInPinImpl) );
1175 return E_OUTOFMEMORY;
1177 QUARTZ_IUnkInit( &This->unk, NULL );
1178 This->pParser = pFilter;
1180 hr = CPinBaseImpl_InitIPin(
1182 This->unk.punkControl,
1184 &pFilter->basefilter,
1187 &inputpinhandlers );
1189 if ( SUCCEEDED(hr) )
1191 hr = CMemInputPinBaseImpl_InitIMemInputPin(
1193 This->unk.punkControl,
1197 CPinBaseImpl_UninitIPin( &This->pin );
1203 QUARTZ_FreeObj(This);
1207 This->unk.pEntries = InPinIFEntries;
1208 This->unk.dwEntries = sizeof(InPinIFEntries)/sizeof(InPinIFEntries[0]);
1209 This->unk.pOnFinalRelease = QUARTZ_DestroyParserInPin;
1213 TRACE("returned successfully.\n");
1219 /***************************************************************************
1221 * new/delete CParserOutPinImpl
1225 /* can I use offsetof safely? - FIXME? */
1226 static QUARTZ_IFEntry OutPinIFEntries[] =
1228 { &IID_IPin, offsetof(CParserOutPinImpl,pin)-offsetof(CParserOutPinImpl,unk) },
1229 { &IID_IQualityControl, offsetof(CParserOutPinImpl,qcontrol)-offsetof(CParserOutPinImpl,unk) },
1230 { &IID_IMediaSeeking, offsetof(CParserOutPinImpl,mediaseeking)-offsetof(CParserOutPinImpl,unk) },
1231 { &IID_IMediaPosition, offsetof(CParserOutPinImpl,mediaposition)-offsetof(CParserOutPinImpl,unk) },
1234 static void QUARTZ_DestroyParserOutPin(IUnknown* punk)
1236 CParserOutPinImpl_THIS(punk,unk);
1238 TRACE( "(%p)\n", This );
1240 QUARTZ_MediaType_Free( &This->m_mtOut );
1241 if ( This->m_pOutPinAllocator != NULL )
1242 IMemAllocator_Release(This->m_pOutPinAllocator);
1244 CParserOutPinImpl_UninitIMediaPosition(This);
1245 CParserOutPinImpl_UninitIMediaSeeking(This);
1246 CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
1247 CPinBaseImpl_UninitIPin( &This->pin );
1251 HRESULT QUARTZ_CreateParserOutPin(
1252 CParserImpl* pFilter,
1253 CRITICAL_SECTION* pcsPin,
1254 CParserOutPinImpl** ppPin,
1256 LPCWSTR pwszPinName )
1258 CParserOutPinImpl* This = NULL;
1261 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
1263 This = (CParserOutPinImpl*)
1264 QUARTZ_AllocObj( sizeof(CParserOutPinImpl) );
1266 return E_OUTOFMEMORY;
1268 QUARTZ_IUnkInit( &This->unk, NULL );
1269 This->pParser = pFilter;
1270 This->nStreamIndex = nStreamIndex;
1271 ZeroMemory( &This->m_mtOut, sizeof(AM_MEDIA_TYPE) );
1272 This->m_pOutPinAllocator = NULL;
1273 This->m_pUserData = NULL;
1274 This->m_bReqUsed = FALSE;
1275 This->m_pReqSample = NULL;
1276 This->m_llReqStart = 0;
1277 This->m_lReqLength = 0;
1278 This->m_rtReqStart = 0;
1279 This->m_rtReqStop = 0;
1280 This->m_dwSampleFlags = 0;
1283 hr = CPinBaseImpl_InitIPin(
1285 This->unk.punkControl,
1287 &pFilter->basefilter,
1290 &outputpinhandlers );
1292 if ( SUCCEEDED(hr) )
1294 hr = CQualityControlPassThruImpl_InitIQualityControl(
1296 This->unk.punkControl,
1298 if ( SUCCEEDED(hr) )
1300 hr = CParserOutPinImpl_InitIMediaSeeking(This);
1301 if ( SUCCEEDED(hr) )
1303 hr = CParserOutPinImpl_InitIMediaPosition(This);
1306 CParserOutPinImpl_UninitIMediaSeeking(This);
1311 CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
1316 CPinBaseImpl_UninitIPin( &This->pin );
1322 QUARTZ_FreeObj(This);
1326 This->unk.pEntries = OutPinIFEntries;
1327 This->unk.dwEntries = sizeof(OutPinIFEntries)/sizeof(OutPinIFEntries[0]);
1328 This->unk.pOnFinalRelease = QUARTZ_DestroyParserOutPin;
1332 TRACE("returned successfully.\n");
1338 /***************************************************************************
1340 * IMediaSeeking for CParserOutPinImpl
1344 static HRESULT WINAPI
1345 IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj)
1347 CParserOutPinImpl_THIS(iface,mediaseeking);
1349 TRACE("(%p)->()\n",This);
1351 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
1355 IMediaSeeking_fnAddRef(IMediaSeeking* iface)
1357 CParserOutPinImpl_THIS(iface,mediaseeking);
1359 TRACE("(%p)->()\n",This);
1361 return IUnknown_AddRef(This->unk.punkControl);
1365 IMediaSeeking_fnRelease(IMediaSeeking* iface)
1367 CParserOutPinImpl_THIS(iface,mediaseeking);
1369 TRACE("(%p)->()\n",This);
1371 return IUnknown_Release(This->unk.punkControl);
1375 static HRESULT WINAPI
1376 IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
1378 CParserOutPinImpl_THIS(iface,mediaseeking);
1379 HRESULT hr = E_NOTIMPL;
1381 TRACE("(%p)->(%p)\n",This,pdwCaps);
1383 if ( pdwCaps == NULL )
1386 EnterCriticalSection( &This->pParser->m_csParser );
1387 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
1389 FIXME("(%p)->(%p) not implemented\n",This,pdwCaps);
1393 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, pdwCaps );
1395 LeaveCriticalSection( &This->pParser->m_csParser );
1400 static HRESULT WINAPI
1401 IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
1403 CParserOutPinImpl_THIS(iface,mediaseeking);
1404 HRESULT hr = E_NOTIMPL;
1407 TRACE("(%p)->(%p)\n",This,pdwCaps);
1409 if ( pdwCaps == NULL )
1412 EnterCriticalSection( &This->pParser->m_csParser );
1413 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
1415 FIXME("(%p)->(%p) not implemented\n",This,pdwCaps);
1419 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
1420 if ( SUCCEEDED(hr) )
1423 if ( dwCaps == *pdwCaps )
1433 LeaveCriticalSection( &This->pParser->m_csParser );
1440 static HRESULT WINAPI
1441 IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat)
1443 CParserOutPinImpl_THIS(iface,mediaseeking);
1444 HRESULT hr = E_NOTIMPL;
1446 TRACE("(%p)->(%s)\n",This,debugstr_guid(pidFormat));
1448 if ( pidFormat == NULL )
1451 EnterCriticalSection( &This->pParser->m_csParser );
1452 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1454 FIXME("(%p)->(%s) not implemented\n",This,debugstr_guid(pidFormat));
1458 hr = This->pParser->m_pHandler->pIsTimeFormatSupported( This->pParser, pidFormat );
1460 LeaveCriticalSection( &This->pParser->m_csParser );
1465 static HRESULT WINAPI
1466 IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat)
1468 CParserOutPinImpl_THIS(iface,mediaseeking);
1471 TRACE("(%p)->(%p)\n",This,pidFormat);
1473 EnterCriticalSection( &This->pParser->m_csParser );
1474 hr = CParserImpl_GetPreferredTimeFormat( This->pParser, pidFormat );
1475 LeaveCriticalSection( &This->pParser->m_csParser );
1480 static HRESULT WINAPI
1481 IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat)
1483 CParserOutPinImpl_THIS(iface,mediaseeking);
1484 HRESULT hr = E_NOTIMPL;
1486 TRACE("(%p)->(%p)\n",This,pidFormat);
1488 if ( pidFormat == NULL )
1491 EnterCriticalSection( &This->pParser->m_csParser );
1492 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1494 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1498 memcpy( pidFormat, &This->pParser->m_guidTimeFormat, sizeof(GUID) );
1500 LeaveCriticalSection( &This->pParser->m_csParser );
1505 static HRESULT WINAPI
1506 IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
1508 CParserOutPinImpl_THIS(iface,mediaseeking);
1509 HRESULT hr = E_NOTIMPL;
1511 TRACE("(%p)->(%p)\n",This,pidFormat);
1513 if ( pidFormat == NULL )
1516 EnterCriticalSection( &This->pParser->m_csParser );
1517 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1519 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1523 hr = IsEqualGUID( pidFormat, &This->pParser->m_guidTimeFormat ) ? S_OK : S_FALSE;
1525 LeaveCriticalSection( &This->pParser->m_csParser );
1530 static HRESULT WINAPI
1531 IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
1533 CParserOutPinImpl_THIS(iface,mediaseeking);
1534 HRESULT hr = E_NOTIMPL;
1536 TRACE("(%p)->(%p)\n",This,pidFormat);
1538 if ( pidFormat == NULL )
1541 EnterCriticalSection( &This->pParser->m_csParser );
1542 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1544 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1548 if ( This->pParser->m_pHandler->pIsTimeFormatSupported( This->pParser, pidFormat ) == S_OK )
1550 memcpy( &This->pParser->m_guidTimeFormat, pidFormat, sizeof(GUID) );
1553 LeaveCriticalSection( &This->pParser->m_csParser );
1558 static HRESULT WINAPI
1559 IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
1561 CParserOutPinImpl_THIS(iface,mediaseeking);
1562 HRESULT hr = E_NOTIMPL;
1564 TRACE("(%p)->(%p)\n",This,pllDuration);
1566 if ( pllDuration == NULL )
1569 EnterCriticalSection( &This->pParser->m_csParser );
1570 if ( This->pParser->m_pHandler->pGetDuration == NULL )
1572 FIXME("(%p)->(%p) not implemented\n",This,pllDuration);
1576 hr = This->pParser->m_pHandler->pGetDuration( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllDuration );
1578 LeaveCriticalSection( &This->pParser->m_csParser );
1583 static HRESULT WINAPI
1584 IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos)
1586 CParserOutPinImpl_THIS(iface,mediaseeking);
1587 HRESULT hr = E_NOTIMPL;
1589 TRACE("(%p)->(%p)\n",This,pllPos);
1591 if ( pllPos == NULL )
1594 EnterCriticalSection( &This->pParser->m_csParser );
1595 if ( This->pParser->m_pHandler->pGetStopPos == NULL )
1597 FIXME("(%p)->(%p) not implemented\n",This,pllPos);
1601 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllPos );
1603 LeaveCriticalSection( &This->pParser->m_csParser );
1608 static HRESULT WINAPI
1609 IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos)
1611 CParserOutPinImpl_THIS(iface,mediaseeking);
1612 HRESULT hr = E_NOTIMPL;
1614 TRACE("(%p)->(%p)\n",This,pllPos);
1616 if ( pllPos == NULL )
1619 EnterCriticalSection( &This->pParser->m_csParser );
1620 if ( This->pParser->m_pHandler->pGetCurPos == NULL )
1622 FIXME("(%p)->(%p) not implemented\n",This,pllPos);
1626 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllPos );
1628 LeaveCriticalSection( &This->pParser->m_csParser );
1633 static HRESULT WINAPI
1634 IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn)
1636 CParserOutPinImpl_THIS(iface,mediaseeking);
1638 FIXME("(%p)->() stub!\n",This);
1643 static HRESULT WINAPI
1644 IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags)
1646 CParserOutPinImpl_THIS(iface,mediaseeking);
1648 FIXME("(%p)->() stub!\n",This);
1653 static HRESULT WINAPI
1654 IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop)
1656 CParserOutPinImpl_THIS(iface,mediaseeking);
1657 HRESULT hr = E_NOTIMPL;
1659 TRACE("(%p)->(%p,%p)\n",This,pllCur,pllStop);
1661 if ( pllCur == NULL || pllStop == NULL )
1664 EnterCriticalSection( &This->pParser->m_csParser );
1665 if ( This->pParser->m_pHandler->pGetCurPos == NULL ||
1666 This->pParser->m_pHandler->pGetStopPos == NULL )
1668 FIXME("(%p)->(%p,%p) not implemented\n",This,pllCur,pllStop);
1672 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllCur );
1673 if ( SUCCEEDED(hr) )
1674 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllStop );
1676 LeaveCriticalSection( &This->pParser->m_csParser );
1681 static HRESULT WINAPI
1682 IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast)
1684 CParserOutPinImpl_THIS(iface,mediaseeking);
1686 FIXME("(%p)->() stub!\n",This);
1691 static HRESULT WINAPI
1692 IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate)
1694 CParserOutPinImpl_THIS(iface,mediaseeking);
1696 FIXME("(%p)->() stub!\n",This);
1701 static HRESULT WINAPI
1702 IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate)
1704 CParserOutPinImpl_THIS(iface,mediaseeking);
1706 FIXME("(%p)->() stub!\n",This);
1711 static HRESULT WINAPI
1712 IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll)
1714 CParserOutPinImpl_THIS(iface,mediaseeking);
1716 FIXME("(%p)->() stub!\n",This);
1724 static ICOM_VTABLE(IMediaSeeking) imediaseeking =
1726 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1727 /* IUnknown fields */
1728 IMediaSeeking_fnQueryInterface,
1729 IMediaSeeking_fnAddRef,
1730 IMediaSeeking_fnRelease,
1731 /* IMediaSeeking fields */
1732 IMediaSeeking_fnGetCapabilities,
1733 IMediaSeeking_fnCheckCapabilities,
1734 IMediaSeeking_fnIsFormatSupported,
1735 IMediaSeeking_fnQueryPreferredFormat,
1736 IMediaSeeking_fnGetTimeFormat,
1737 IMediaSeeking_fnIsUsingTimeFormat,
1738 IMediaSeeking_fnSetTimeFormat,
1739 IMediaSeeking_fnGetDuration,
1740 IMediaSeeking_fnGetStopPosition,
1741 IMediaSeeking_fnGetCurrentPosition,
1742 IMediaSeeking_fnConvertTimeFormat,
1743 IMediaSeeking_fnSetPositions,
1744 IMediaSeeking_fnGetPositions,
1745 IMediaSeeking_fnGetAvailable,
1746 IMediaSeeking_fnSetRate,
1747 IMediaSeeking_fnGetRate,
1748 IMediaSeeking_fnGetPreroll,
1751 HRESULT CParserOutPinImpl_InitIMediaSeeking( CParserOutPinImpl* This )
1753 TRACE("(%p)\n",This);
1754 ICOM_VTBL(&This->mediaseeking) = &imediaseeking;
1759 void CParserOutPinImpl_UninitIMediaSeeking( CParserOutPinImpl* This )
1761 TRACE("(%p)\n",This);
1764 /***************************************************************************
1766 * IMediaPosition for CParserOutPinImpl
1770 static HRESULT WINAPI
1771 IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj)
1773 CParserOutPinImpl_THIS(iface,mediaposition);
1775 TRACE("(%p)->()\n",This);
1777 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
1781 IMediaPosition_fnAddRef(IMediaPosition* iface)
1783 CParserOutPinImpl_THIS(iface,mediaposition);
1785 TRACE("(%p)->()\n",This);
1787 return IUnknown_AddRef(This->unk.punkControl);
1791 IMediaPosition_fnRelease(IMediaPosition* iface)
1793 CParserOutPinImpl_THIS(iface,mediaposition);
1795 TRACE("(%p)->()\n",This);
1797 return IUnknown_Release(This->unk.punkControl);
1800 static HRESULT WINAPI
1801 IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo)
1803 CParserOutPinImpl_THIS(iface,mediaposition);
1805 FIXME("(%p)->() stub!\n",This);
1810 static HRESULT WINAPI
1811 IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
1813 CParserOutPinImpl_THIS(iface,mediaposition);
1815 FIXME("(%p)->() stub!\n",This);
1820 static HRESULT WINAPI
1821 IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
1823 CParserOutPinImpl_THIS(iface,mediaposition);
1825 FIXME("(%p)->() stub!\n",This);
1830 static HRESULT WINAPI
1831 IMediaPosition_fnInvoke(IMediaPosition* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1833 CParserOutPinImpl_THIS(iface,mediaposition);
1835 FIXME("(%p)->() stub!\n",This);
1841 static HRESULT WINAPI
1842 IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
1844 CParserOutPinImpl_THIS(iface,mediaposition);
1845 HRESULT hr = E_NOTIMPL;
1848 TRACE("(%p)->(%p)\n",This,prefTime);
1850 if ( prefTime == NULL )
1853 EnterCriticalSection( &This->pParser->m_csParser );
1854 if ( This->pParser->m_pHandler->pGetDuration == NULL )
1856 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1860 hr = This->pParser->m_pHandler->pGetDuration( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1861 if ( SUCCEEDED(hr) )
1862 *prefTime = (REFTIME)llPos;
1864 LeaveCriticalSection( &This->pParser->m_csParser );
1869 static HRESULT WINAPI
1870 IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
1872 CParserOutPinImpl_THIS(iface,mediaposition);
1873 HRESULT hr = E_NOTIMPL;
1876 FIXME("(%p)->() stub!\n",This);
1879 EnterCriticalSection( &This->pParser->m_csParser );
1880 if ( This->pParser->m_pHandler->pSetCurPos == NULL )
1882 FIXME("(%p)->() not implemented\n",This);
1886 llPos = (LONGLONG)refTime;
1887 hr = This->pParser->m_pHandler->pSetCurPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, llPos );
1888 /* FIXME - flush all streams. */
1890 LeaveCriticalSection( &This->pParser->m_csParser );
1896 static HRESULT WINAPI
1897 IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
1899 CParserOutPinImpl_THIS(iface,mediaposition);
1900 HRESULT hr = E_NOTIMPL;
1903 TRACE("(%p)->(%p)\n",This,prefTime);
1905 if ( prefTime == NULL )
1908 EnterCriticalSection( &This->pParser->m_csParser );
1909 if ( This->pParser->m_pHandler->pGetCurPos == NULL )
1911 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1915 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1916 if ( SUCCEEDED(hr) )
1917 *prefTime = (REFTIME)llPos;
1919 LeaveCriticalSection( &This->pParser->m_csParser );
1924 static HRESULT WINAPI
1925 IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
1927 CParserOutPinImpl_THIS(iface,mediaposition);
1928 HRESULT hr = E_NOTIMPL;
1931 TRACE("(%p)->(%p)\n",This,prefTime);
1933 if ( prefTime == NULL )
1936 EnterCriticalSection( &This->pParser->m_csParser );
1937 if ( This->pParser->m_pHandler->pGetStopPos == NULL )
1939 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1943 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1944 if ( SUCCEEDED(hr) )
1945 *prefTime = (REFTIME)llPos;
1947 LeaveCriticalSection( &This->pParser->m_csParser );
1952 static HRESULT WINAPI
1953 IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
1955 CParserOutPinImpl_THIS(iface,mediaposition);
1956 HRESULT hr = E_NOTIMPL;
1959 TRACE("(%p)->()\n",This);
1961 EnterCriticalSection( &This->pParser->m_csParser );
1962 if ( This->pParser->m_pHandler->pSetStopPos == NULL )
1964 FIXME("(%p)->() not implemented\n",This);
1968 llPos = (LONGLONG)refTime;
1969 hr = This->pParser->m_pHandler->pSetStopPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, llPos );
1971 LeaveCriticalSection( &This->pParser->m_csParser );
1976 static HRESULT WINAPI
1977 IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
1979 CParserOutPinImpl_THIS(iface,mediaposition);
1981 FIXME("(%p)->() stub!\n",This);
1986 static HRESULT WINAPI
1987 IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
1989 CParserOutPinImpl_THIS(iface,mediaposition);
1991 FIXME("(%p)->() stub!\n",This);
1996 static HRESULT WINAPI
1997 IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
1999 CParserOutPinImpl_THIS(iface,mediaposition);
2001 return IMediaSeeking_SetRate(CParserOutPinImpl_IMediaSeeking(This),dblRate);
2004 static HRESULT WINAPI
2005 IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
2007 CParserOutPinImpl_THIS(iface,mediaposition);
2009 return IMediaSeeking_GetRate(CParserOutPinImpl_IMediaSeeking(This),pdblRate);
2012 static HRESULT WINAPI
2013 IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
2015 CParserOutPinImpl_THIS(iface,mediaposition);
2016 HRESULT hr = E_NOTIMPL;
2019 TRACE("(%p)->(%p)\n",This,pCanSeek);
2021 if ( pCanSeek == NULL )
2024 EnterCriticalSection( &This->pParser->m_csParser );
2025 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
2027 FIXME("(%p)->(%p) not implemented\n",This,pCanSeek);
2031 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
2032 if ( SUCCEEDED(hr) )
2034 *pCanSeek = (dwCaps & AM_SEEKING_CanSeekForwards) ? OATRUE : OAFALSE;
2038 LeaveCriticalSection( &This->pParser->m_csParser );
2043 static HRESULT WINAPI
2044 IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
2046 CParserOutPinImpl_THIS(iface,mediaposition);
2047 HRESULT hr = E_NOTIMPL;
2050 TRACE("(%p)->(%p)\n",This,pCanSeek);
2052 if ( pCanSeek == NULL )
2055 EnterCriticalSection( &This->pParser->m_csParser );
2056 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
2058 FIXME("(%p)->(%p) not implemented\n",This,pCanSeek);
2062 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
2063 if ( SUCCEEDED(hr) )
2065 *pCanSeek = (dwCaps & AM_SEEKING_CanSeekBackwards) ? OATRUE : OAFALSE;
2069 LeaveCriticalSection( &This->pParser->m_csParser );
2075 static ICOM_VTABLE(IMediaPosition) imediaposition =
2077 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2078 /* IUnknown fields */
2079 IMediaPosition_fnQueryInterface,
2080 IMediaPosition_fnAddRef,
2081 IMediaPosition_fnRelease,
2082 /* IDispatch fields */
2083 IMediaPosition_fnGetTypeInfoCount,
2084 IMediaPosition_fnGetTypeInfo,
2085 IMediaPosition_fnGetIDsOfNames,
2086 IMediaPosition_fnInvoke,
2087 /* IMediaPosition fields */
2088 IMediaPosition_fnget_Duration,
2089 IMediaPosition_fnput_CurrentPosition,
2090 IMediaPosition_fnget_CurrentPosition,
2091 IMediaPosition_fnget_StopTime,
2092 IMediaPosition_fnput_StopTime,
2093 IMediaPosition_fnget_PrerollTime,
2094 IMediaPosition_fnput_PrerollTime,
2095 IMediaPosition_fnput_Rate,
2096 IMediaPosition_fnget_Rate,
2097 IMediaPosition_fnCanSeekForward,
2098 IMediaPosition_fnCanSeekBackward,
2102 HRESULT CParserOutPinImpl_InitIMediaPosition( CParserOutPinImpl* This )
2104 TRACE("(%p)\n",This);
2105 ICOM_VTBL(&This->mediaposition) = &imediaposition;
2110 void CParserOutPinImpl_UninitIMediaPosition( CParserOutPinImpl* This )
2112 TRACE("(%p)\n",This);