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 )
176 void CParserImplThread_MemDecommit( CParserImpl* This )
179 IMemAllocator* pAlloc;
181 TRACE("(%p)\n",This);
183 if ( This->m_pAllocator != NULL )
184 IMemAllocator_Decommit( This->m_pAllocator );
186 if ( This->m_ppOutPins != NULL && This->m_cOutStreams > 0 )
188 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
190 pAlloc = This->m_ppOutPins[nIndex]->m_pOutPinAllocator;
191 if ( pAlloc != NULL )
192 IMemAllocator_Decommit( pAlloc );
197 static HRESULT CParserImplThread_SendFlush( CParserImpl* This )
202 CParserOutPinImpl* pOutPin;
204 TRACE("(%p)\n",This);
206 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
208 pOutPin = This->m_ppOutPins[nIndex];
209 hr = CPinBaseImpl_SendBeginFlush(&pOutPin->pin);
212 if ( SUCCEEDED(hrRet) )
217 if ( hr != S_OK && hrRet == S_OK )
219 hr = CPinBaseImpl_SendEndFlush(&pOutPin->pin);
228 static void CParserImplThread_ErrorAbort( CParserImpl* This, HRESULT hr )
230 CBaseFilterImpl_MediaEventNotify(
231 &This->basefilter,EC_ERRORABORT,(LONG_PTR)hr,(LONG_PTR)0);
232 CParserImplThread_SendEndOfStream(This);
236 void CParserImplThread_ResetAllStreams( CParserImpl* This )
240 if ( This->m_pHandler->pSetCurPos != NULL )
242 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
243 This->m_pHandler->pSetCurPos(This,
244 &This->m_guidTimeFormat,nIndex,(LONGLONG)0);
249 HRESULT CParserImplThread_ProcessNextSample( CParserImpl* This )
251 IMediaSample* pSample;
255 CParserOutPinImpl* pOutPin;
260 if ( PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_REMOVE ) )
263 switch ( msg.message )
265 case QUARTZ_MSG_EXITTHREAD:
266 TRACE("(%p) EndThread\n",This);
267 CParserImplThread_FlushAllPendingSamples(This);
268 CParserImplThread_ClearAllRequests(This);
269 CParserImplThread_SendFlush(This);
270 CParserImplThread_SendEndOfStream(This);
271 This->m_bSendEOS = FALSE;
273 CParserImplThread_ResetAllStreams(This);
274 CParserImplThread_MemDecommit(This);
276 TRACE("(%p) exit thread\n",This);
278 case QUARTZ_MSG_SEEK:
279 FIXME("(%p) Seek\n",This);
280 CParserImplThread_FlushAllPendingSamples(This);
281 hr = CParserImplThread_SendFlush(This);
282 CParserImplThread_SendEndOfStream(This);
283 /* FIXME - process seeking. */
284 /* FIXME - Send NewSegment. */
287 FIXME( "invalid message %04u\n", (unsigned)msg.message );
289 CParserImplThread_ErrorAbort(This,hr);
295 hr = IAsyncReader_WaitForNext(This->m_pReader,PARSER_POLL_INTERVAL,&pSample,&dwContext);
296 nIndex = (ULONG)dwContext;
297 if ( hr != VFW_E_TIMEOUT )
302 CParserImplThread_ErrorAbort(This,hr);
306 pOutPin = This->m_ppOutPins[nIndex];
307 if ( pOutPin != NULL && pOutPin->m_bReqUsed )
309 if ( This->m_pHandler->pProcessSample != NULL )
310 hr = This->m_pHandler->pProcessSample(This,nIndex,pOutPin->m_llReqStart,pOutPin->m_lReqLength,pOutPin->m_pReqSample);
312 IMediaSample_SetSyncPoint( pOutPin->m_pReqSample, (pOutPin->m_dwSampleFlags & AM_SAMPLE_SPLICEPOINT) ? TRUE : FALSE );
313 IMediaSample_SetPreroll( pOutPin->m_pReqSample, (pOutPin->m_dwSampleFlags & AM_SAMPLE_PREROLL) ? TRUE : FALSE );
314 IMediaSample_SetDiscontinuity( pOutPin->m_pReqSample, (pOutPin->m_dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) ? TRUE : FALSE );
318 if ( pOutPin->m_pOutPinAllocator != NULL &&
319 pOutPin->m_pOutPinAllocator != This->m_pAllocator )
321 /* if pin has its own allocator, sample must be copied */
322 hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 );
325 hr = QUARTZ_IMediaSample_Copy(
326 pSample, pOutPin->m_pReqSample, TRUE );
328 hr = CPinBaseImpl_SendSample(&pOutPin->pin,pSample);
329 IMediaSample_Release(pSample);
334 hr = CPinBaseImpl_SendSample(&pOutPin->pin,pOutPin->m_pReqSample);
339 CParserImplThread_ErrorAbort(This,hr);
341 IMediaSample_Release(pOutPin->m_pReqSample);
342 pOutPin->m_pReqSample = NULL;
343 pOutPin->m_bReqUsed = FALSE;
349 TRACE("return %08lx\n",hr);
355 DWORD WINAPI CParserImplThread_Entry( LPVOID pv )
357 CParserImpl* This = (CParserImpl*)pv;
361 REFERENCE_TIME rtSampleTimeStart, rtSampleTimeEnd;
365 REFERENCE_TIME rtReqStart, rtReqStop;
366 IMediaSample* pSample;
369 /* initialize the message queue. */
370 PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE );
372 CParserImplThread_ClearAllRequests(This);
374 /* resume the owner thread. */
375 SetEvent( This->m_hEventInit );
377 TRACE( "Enter message loop.\n" );
384 /* Get the next request. */
385 hr = This->m_pHandler->pGetNextRequest( This, &nIndex, &llReqStart, &lReqLength, &rtReqStart, &rtReqStop, &dwSampleFlags );
388 CParserImplThread_ErrorAbort(This,hr);
393 /* Flush pending samples. */
395 while ( CParserImplThread_HasPendingSamples(This) )
397 hr = CParserImplThread_ProcessNextSample(This);
403 /* notification is already sent */
407 /* Send End Of Stream. */
408 hr = CParserImplThread_SendEndOfStream(This);
411 /* notification is already sent */
416 hr = CParserImplThread_ProcessNextSample(This);
419 /* notification is already sent */
424 if ( This->m_ppOutPins[nIndex]->pin.pPinConnectedTo == NULL )
427 rtSampleTimeStart = This->basefilter.rtStart + llReqStart * QUARTZ_TIMEUNITS;
428 rtSampleTimeEnd = (llReqStart + lReqLength) * QUARTZ_TIMEUNITS;
432 if ( !This->m_ppOutPins[nIndex]->m_bReqUsed )
434 hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 );
437 CParserImplThread_ErrorAbort(This,hr);
440 hr = IMediaSample_SetTime(pSample,&rtSampleTimeStart,&rtSampleTimeEnd);
442 hr = IAsyncReader_Request(This->m_pReader,pSample,nIndex);
445 CParserImplThread_ErrorAbort(This,hr);
449 This->m_ppOutPins[nIndex]->m_bReqUsed = TRUE;
450 This->m_ppOutPins[nIndex]->m_pReqSample = pSample;
451 This->m_ppOutPins[nIndex]->m_llReqStart = llReqStart;
452 This->m_ppOutPins[nIndex]->m_lReqLength = lReqLength;
453 This->m_ppOutPins[nIndex]->m_rtReqStart = rtSampleTimeStart;
454 This->m_ppOutPins[nIndex]->m_rtReqStop = rtSampleTimeEnd;
455 This->m_ppOutPins[nIndex]->m_dwSampleFlags = dwSampleFlags;
460 hr = CParserImplThread_ProcessNextSample(This);
463 /* notification is already sent */
468 This->m_dwThreadId = 0;
469 This->basefilter.bIntermediateState = FALSE;
470 SetEvent( This->m_hEventInit );
475 /***************************************************************************
477 * CParserImpl internal methods
482 void CParserImpl_SetAsyncReader( CParserImpl* This, IAsyncReader* pReader )
484 if ( This->m_pReader != NULL )
486 IAsyncReader_Release( This->m_pReader );
487 This->m_pReader = NULL;
489 if ( pReader != NULL )
491 This->m_pReader = pReader;
492 IAsyncReader_AddRef(This->m_pReader);
497 void CParserImpl_ReleaseOutPins( CParserImpl* This )
501 if ( This->m_ppOutPins != NULL )
503 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
505 if ( This->m_ppOutPins[nIndex] != NULL )
507 IUnknown_Release(This->m_ppOutPins[nIndex]->unk.punkControl);
508 This->m_ppOutPins[nIndex] = NULL;
511 QUARTZ_FreeMem(This->m_ppOutPins);
512 This->m_ppOutPins = NULL;
514 This->m_cOutStreams = 0;
518 BOOL CParserImpl_OutPinsAreConnected( CParserImpl* This )
520 QUARTZ_CompListItem* pItem;
525 QUARTZ_CompList_Lock( This->basefilter.pOutPins );
526 pItem = QUARTZ_CompList_GetFirst( This->basefilter.pOutPins );
527 while ( pItem != NULL )
531 pPin = (IPin*)QUARTZ_CompList_GetItemPtr(pItem);
533 hr = IPin_ConnectedTo(pPin,&pPinPeer);
534 if ( hr == S_OK && pPinPeer != NULL )
536 IPin_Release(pPinPeer);
539 pItem = QUARTZ_CompList_GetNext( This->basefilter.pOutPins, pItem );
541 QUARTZ_CompList_Unlock( This->basefilter.pOutPins );
547 void CParserImpl_ReleaseListOfOutPins( CParserImpl* This )
549 QUARTZ_CompListItem* pItem;
551 QUARTZ_CompList_Lock( This->basefilter.pOutPins );
554 pItem = QUARTZ_CompList_GetFirst( This->basefilter.pOutPins );
557 QUARTZ_CompList_RemoveComp(
558 This->basefilter.pOutPins,
559 QUARTZ_CompList_GetItemPtr(pItem) );
561 QUARTZ_CompList_Unlock( This->basefilter.pOutPins );
566 HRESULT CParserImpl_BeginThread( CParserImpl* This )
571 if ( This->m_bIsRunning )
573 TRACE("(%p) - already running\n",This);
577 This->m_hEventInit = CreateEventA(NULL,TRUE,FALSE,NULL);
578 if ( This->m_hEventInit == (HANDLE)NULL )
579 return E_OUTOFMEMORY;
581 /* create the processing thread. */
582 This->m_hThread = CreateThread(
584 CParserImplThread_Entry,
586 0, &This->m_dwThreadId );
587 if ( This->m_hThread == (HANDLE)NULL )
589 CloseHandle( This->m_hEventInit );
590 This->m_hEventInit = (HANDLE)NULL;
594 hEvents[0] = This->m_hEventInit;
595 hEvents[1] = This->m_hThread;
597 dwRes = WaitForMultipleObjects(2,hEvents,FALSE,INFINITE);
599 ResetEvent( This->m_hEventInit );
600 CloseHandle( This->m_hThread );
601 This->m_hThread = (HANDLE)NULL;
603 if ( dwRes != WAIT_OBJECT_0 )
606 This->m_bIsRunning = TRUE;
612 BOOL CParserImpl_EndThread( CParserImpl* This, BOOL bAsync )
616 TRACE("(%p)\n",This);
617 dwThreadId = This->m_dwThreadId;
618 if ( This->m_hEventInit != (HANDLE)NULL )
620 if ( dwThreadId != 0 )
622 dwThreadId, QUARTZ_MSG_EXITTHREAD, 0, 0 );
624 WaitForSingleObject( This->m_hEventInit, 0 ) == WAIT_TIMEOUT )
627 WaitForSingleObject( This->m_hEventInit, INFINITE );
628 CloseHandle( This->m_hEventInit );
629 This->m_bIsRunning = FALSE;
630 This->m_hEventInit = (HANDLE)NULL;
637 HRESULT CParserImpl_MemCommit( CParserImpl* This )
641 IMemAllocator* pAlloc;
643 TRACE("(%p)\n",This);
645 if ( This->m_pAllocator == NULL )
648 hr = IMemAllocator_Commit( This->m_pAllocator );
652 if ( This->m_ppOutPins != NULL && This->m_cOutStreams > 0 )
654 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
656 pAlloc = This->m_ppOutPins[nIndex]->m_pOutPinAllocator;
657 if ( pAlloc != NULL && pAlloc != This->m_pAllocator )
659 hr = IMemAllocator_Commit( pAlloc );
670 HRESULT CParserImpl_GetPreferredTimeFormat( CParserImpl* This, GUID* pguidFormat )
672 static const GUID* tryformats[] =
674 &TIME_FORMAT_MEDIA_TIME,
683 if ( This->m_pHandler->pIsTimeFormatSupported == NULL )
687 while ( tryformats[n] != NULL )
689 if ( This->m_pHandler->pIsTimeFormatSupported( This, tryformats[n] ) == S_OK )
691 memcpy( pguidFormat, tryformats[n], sizeof(GUID) );
702 /***************************************************************************
704 * CParserImpl methods
708 static HRESULT CParserImpl_OnActive( CBaseFilterImpl* pImpl )
710 CParserImpl_THIS(pImpl,basefilter);
712 TRACE( "(%p)\n", This );
714 if ( !CParserImpl_OutPinsAreConnected(This) )
720 static HRESULT CParserImpl_OnInactive( CBaseFilterImpl* pImpl )
722 CParserImpl_THIS(pImpl,basefilter);
725 TRACE( "(%p)\n", This );
727 if ( !CParserImpl_OutPinsAreConnected(This) )
730 hr = CParserImpl_MemCommit(This);
734 if ( This->basefilter.fstate == State_Stopped )
735 CParserImpl_EndThread(This,FALSE);
737 hr = CParserImpl_BeginThread(This);
740 FIXME("CParserImpl_BeginThread returns %08lx\n",hr);
741 CParserImpl_EndThread(This,FALSE);
748 static HRESULT CParserImpl_OnStop( CBaseFilterImpl* pImpl )
750 CParserImpl_THIS(pImpl,basefilter);
752 TRACE( "(%p)\n", This );
754 This->basefilter.bIntermediateState = TRUE;
755 if ( !CParserImpl_EndThread(This,TRUE) )
756 return VFW_S_STATE_INTERMEDIATE;
758 This->basefilter.bIntermediateState = FALSE;
763 static const CBaseFilterHandlers filterhandlers =
765 CParserImpl_OnActive, /* pOnActive */
766 CParserImpl_OnInactive, /* pOnInactive */
767 CParserImpl_OnStop, /* pOnStop */
771 /***************************************************************************
773 * CParserInPinImpl methods
777 static HRESULT CParserInPinImpl_OnPreConnect( CPinBaseImpl* pImpl, IPin* pPin )
779 CParserInPinImpl_THIS(pImpl,pin);
783 IAsyncReader* pReader = NULL;
784 LPCWSTR pwszOutPinName;
785 IMemAllocator* pAllocActual;
788 TRACE("(%p,%p)\n",This,pPin);
790 if ( This->pParser->m_pHandler->pInitParser == NULL ||
791 This->pParser->m_pHandler->pUninitParser == NULL ||
792 This->pParser->m_pHandler->pGetOutPinName == NULL ||
793 This->pParser->m_pHandler->pGetStreamType == NULL ||
794 This->pParser->m_pHandler->pCheckStreamType == NULL ||
795 This->pParser->m_pHandler->pGetAllocProp == NULL ||
796 This->pParser->m_pHandler->pGetNextRequest == NULL )
798 FIXME("this parser is not implemented.\n");
802 /* at first, release all output pins. */
803 if ( CParserImpl_OutPinsAreConnected(This->pParser) )
805 CParserImpl_ReleaseListOfOutPins(This->pParser);
806 CParserImpl_ReleaseOutPins(This->pParser);
808 CParserImpl_SetAsyncReader( This->pParser, NULL );
809 hr = IPin_QueryInterface( pPin, &IID_IAsyncReader, (void**)&pReader );
812 CParserImpl_SetAsyncReader( This->pParser, pReader );
813 IAsyncReader_Release(pReader);
815 /* initialize parser. */
816 hr = This->pParser->m_pHandler->pInitParser(This->pParser,&This->pParser->m_cOutStreams);
819 This->pParser->m_ppOutPins = (CParserOutPinImpl**)QUARTZ_AllocMem(
820 sizeof(CParserOutPinImpl*) * This->pParser->m_cOutStreams );
821 if ( This->pParser->m_ppOutPins == NULL )
822 return E_OUTOFMEMORY;
823 for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
824 This->pParser->m_ppOutPins[nIndex] = NULL;
826 /* create and initialize an allocator. */
827 hr = This->pParser->m_pHandler->pGetAllocProp(This->pParser,&This->pParser->m_propAlloc);
830 if ( This->pParser->m_propAlloc.cbAlign == 0 )
831 This->pParser->m_propAlloc.cbAlign = 1;
833 if ( This->pParser->m_pAllocator == NULL )
835 hr = QUARTZ_CreateMemoryAllocator(NULL,(void**)&punk);
838 hr = IUnknown_QueryInterface( punk, &IID_IMemAllocator, (void**)&This->pParser->m_pAllocator );
839 IUnknown_Release(punk);
844 hr = IAsyncReader_RequestAllocator(pReader,This->pParser->m_pAllocator,&This->pParser->m_propAlloc,&pAllocActual);
847 IMemAllocator_Release(This->pParser->m_pAllocator);
848 This->pParser->m_pAllocator = pAllocActual;
850 /* create output pins. */
851 for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
853 pwszOutPinName = This->pParser->m_pHandler->pGetOutPinName(This->pParser,nIndex);
854 if ( pwszOutPinName == NULL )
856 hr = QUARTZ_CreateParserOutPin(
858 &This->pParser->m_csParser,
859 &This->pParser->m_ppOutPins[nIndex],
860 nIndex, pwszOutPinName );
862 hr = QUARTZ_CompList_AddTailComp(
863 This->pParser->basefilter.pOutPins,
864 (IUnknown*)&(This->pParser->m_ppOutPins[nIndex]->pin),
868 pmt = &This->pParser->m_ppOutPins[nIndex]->m_mtOut;
869 QUARTZ_MediaType_Free( pmt );
870 ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
871 hr = This->pParser->m_pHandler->pGetStreamType(This->pParser,nIndex,pmt);
874 ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
877 This->pParser->m_ppOutPins[nIndex]->pin.cAcceptTypes = 1;
878 This->pParser->m_ppOutPins[nIndex]->pin.pmtAcceptTypes = pmt;
884 static HRESULT CParserInPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
886 CParserInPinImpl_THIS(pImpl,pin);
888 /* assume the graph is already stopped */
889 /*CParserImpl_OnInactive(&This->pParser->basefilter);*/
890 /*CParserImpl_OnStop(&This->pParser->basefilter);*/
891 if ( This->pParser->m_pHandler->pUninitParser != NULL )
892 This->pParser->m_pHandler->pUninitParser(This->pParser);
893 CParserImpl_SetAsyncReader( This->pParser, NULL );
894 if ( This->pParser->m_pAllocator != NULL )
896 IMemAllocator_Decommit(This->pParser->m_pAllocator);
897 IMemAllocator_Release(This->pParser->m_pAllocator);
898 This->pParser->m_pAllocator = NULL;
904 static HRESULT CParserInPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
906 CParserInPinImpl_THIS(pImpl,pin);
908 TRACE("(%p,%p)\n",This,pmt);
910 if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Stream ) )
916 static const CBasePinHandlers inputpinhandlers =
918 CParserInPinImpl_OnPreConnect, /* pOnPreConnect */
919 NULL, /* pOnPostConnect */
920 CParserInPinImpl_OnDisconnect, /* pOnDisconnect */
921 CParserInPinImpl_CheckMediaType, /* pCheckMediaType */
922 NULL, /* pQualityNotify */
924 NULL, /* pReceiveCanBlock */
925 NULL, /* pEndOfStream */
926 NULL, /* pBeginFlush */
927 NULL, /* pEndFlush */
928 NULL, /* pNewSegment */
931 /***************************************************************************
933 * CParserOutPinImpl methods
937 static HRESULT CParserOutPinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPin )
939 CParserOutPinImpl_THIS(pImpl,pin);
940 ALLOCATOR_PROPERTIES propReq;
941 ALLOCATOR_PROPERTIES propActual;
942 IMemAllocator* pAllocator;
944 BOOL bNewAllocator = FALSE;
946 TRACE("(%p,%p)\n",This,pPin);
948 if ( This->pin.pMemInputPinConnectedTo == NULL )
951 if ( This->m_pOutPinAllocator != NULL )
953 IMemAllocator_Release(This->m_pOutPinAllocator);
954 This->m_pOutPinAllocator = NULL;
957 /* try to use This->pParser->m_pAllocator. */
958 ZeroMemory( &propReq, sizeof(ALLOCATOR_PROPERTIES) );
959 hr = IMemInputPin_GetAllocatorRequirements(
960 This->pin.pMemInputPinConnectedTo, &propReq );
961 if ( propReq.cbAlign != 0 )
963 if ( This->pParser->m_propAlloc.cbAlign != ( This->pParser->m_propAlloc.cbAlign / propReq.cbAlign * propReq.cbAlign ) )
964 bNewAllocator = TRUE;
966 if ( propReq.cbPrefix != 0 )
967 bNewAllocator = TRUE;
968 if ( !bNewAllocator )
970 hr = IMemInputPin_NotifyAllocator(
971 This->pin.pMemInputPinConnectedTo,
972 This->pParser->m_pAllocator, FALSE );
975 This->m_pOutPinAllocator = This->pParser->m_pAllocator;
976 IMemAllocator_AddRef(This->m_pOutPinAllocator);
981 hr = IMemInputPin_GetAllocator(
982 This->pin.pMemInputPinConnectedTo, &pAllocator );
985 hr = IMemAllocator_SetProperties( pAllocator, &This->pParser->m_propAlloc, &propActual );
987 hr = IMemInputPin_NotifyAllocator(
988 This->pin.pMemInputPinConnectedTo, pAllocator, FALSE );
991 IMemAllocator_Release(pAllocator);
995 This->m_pOutPinAllocator = pAllocator;
999 static HRESULT CParserOutPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
1001 CParserOutPinImpl_THIS(pImpl,pin);
1003 if ( This->m_pOutPinAllocator != NULL )
1005 IMemAllocator_Release(This->m_pOutPinAllocator);
1006 This->m_pOutPinAllocator = NULL;
1012 static HRESULT CParserOutPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
1014 CParserOutPinImpl_THIS(pImpl,pin);
1017 TRACE("(%p,%p)\n",This,pmt);
1021 if ( This->pParser->m_pHandler->pCheckStreamType == NULL )
1024 hr = This->pParser->m_pHandler->pCheckStreamType( This->pParser, This->nStreamIndex, pmt );
1032 static const CBasePinHandlers outputpinhandlers =
1034 NULL, /* pOnPreConnect */
1035 CParserOutPinImpl_OnPostConnect, /* pOnPostConnect */
1036 CParserOutPinImpl_OnDisconnect, /* pOnDisconnect */
1037 CParserOutPinImpl_CheckMediaType, /* pCheckMediaType */
1038 NULL, /* pQualityNotify */
1039 OutputPinSync_Receive, /* pReceive */
1040 OutputPinSync_ReceiveCanBlock, /* pReceiveCanBlock */
1041 OutputPinSync_EndOfStream, /* pEndOfStream */
1042 OutputPinSync_BeginFlush, /* pBeginFlush */
1043 OutputPinSync_EndFlush, /* pEndFlush */
1044 OutputPinSync_NewSegment, /* pNewSegment */
1047 /***************************************************************************
1049 * new/delete CParserImpl
1053 /* can I use offsetof safely? - FIXME? */
1054 static QUARTZ_IFEntry FilterIFEntries[] =
1056 { &IID_IPersist, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1057 { &IID_IMediaFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1058 { &IID_IBaseFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1061 static void QUARTZ_DestroyParser(IUnknown* punk)
1063 CParserImpl_THIS(punk,unk);
1065 TRACE( "(%p)\n", This );
1067 if ( This->m_pInPin != NULL )
1068 CParserInPinImpl_OnDisconnect(&This->m_pInPin->pin);
1070 CParserImpl_SetAsyncReader( This, NULL );
1071 if ( This->m_pAllocator != NULL )
1073 IMemAllocator_Release(This->m_pAllocator);
1074 This->m_pAllocator = NULL;
1076 if ( This->m_pInPin != NULL )
1078 IUnknown_Release(This->m_pInPin->unk.punkControl);
1079 This->m_pInPin = NULL;
1081 CParserImpl_ReleaseOutPins( This );
1083 DeleteCriticalSection( &This->m_csParser );
1085 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
1088 HRESULT QUARTZ_CreateParser(
1089 IUnknown* punkOuter,void** ppobj,
1090 const CLSID* pclsidParser,
1091 LPCWSTR pwszParserName,
1092 LPCWSTR pwszInPinName,
1093 const ParserHandlers* pHandler )
1095 CParserImpl* This = NULL;
1098 TRACE("(%p,%p)\n",punkOuter,ppobj);
1100 This = (CParserImpl*)
1101 QUARTZ_AllocObj( sizeof(CParserImpl) );
1103 return E_OUTOFMEMORY;
1104 ZeroMemory( This, sizeof(CParserImpl) );
1106 This->m_pInPin = NULL;
1107 This->m_cOutStreams = 0;
1108 This->m_ppOutPins = NULL;
1109 memcpy( &This->m_guidTimeFormat, &TIME_FORMAT_NONE, sizeof(GUID) );
1110 This->m_pReader = NULL;
1111 This->m_pAllocator = NULL;
1112 ZeroMemory( &This->m_propAlloc, sizeof(ALLOCATOR_PROPERTIES) );
1113 This->m_hEventInit = (HANDLE)NULL;
1114 This->m_bIsRunning = FALSE;
1115 This->m_hThread = (HANDLE)NULL;
1116 This->m_dwThreadId = 0;
1117 This->m_bSendEOS = FALSE;
1118 This->m_pHandler = pHandler;
1119 This->m_pUserData = NULL;
1121 QUARTZ_IUnkInit( &This->unk, punkOuter );
1123 hr = CBaseFilterImpl_InitIBaseFilter(
1125 This->unk.punkControl,
1129 if ( SUCCEEDED(hr) )
1131 /* construct this class. */
1136 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
1142 QUARTZ_FreeObj(This);
1146 This->unk.pEntries = FilterIFEntries;
1147 This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
1148 This->unk.pOnFinalRelease = QUARTZ_DestroyParser;
1149 InitializeCriticalSection( &This->m_csParser );
1151 /* create the input pin. */
1152 hr = QUARTZ_CreateParserInPin(
1157 if ( SUCCEEDED(hr) )
1158 hr = QUARTZ_CompList_AddComp(
1159 This->basefilter.pInPins,
1160 (IUnknown*)&(This->m_pInPin->pin),
1165 IUnknown_Release( This->unk.punkControl );
1169 *ppobj = (void*)&(This->unk);
1171 (void)CParserImpl_GetPreferredTimeFormat( This, &This->m_guidTimeFormat );
1176 /***************************************************************************
1178 * new/delete CParserInPinImpl
1182 /* can I use offsetof safely? - FIXME? */
1183 static QUARTZ_IFEntry InPinIFEntries[] =
1185 { &IID_IPin, offsetof(CParserInPinImpl,pin)-offsetof(CParserInPinImpl,unk) },
1186 { &IID_IMemInputPin, offsetof(CParserInPinImpl,meminput)-offsetof(CParserInPinImpl,unk) },
1189 static void QUARTZ_DestroyParserInPin(IUnknown* punk)
1191 CParserInPinImpl_THIS(punk,unk);
1193 TRACE( "(%p)\n", This );
1195 CPinBaseImpl_UninitIPin( &This->pin );
1196 CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
1199 HRESULT QUARTZ_CreateParserInPin(
1200 CParserImpl* pFilter,
1201 CRITICAL_SECTION* pcsPin,
1202 CParserInPinImpl** ppPin,
1203 LPCWSTR pwszPinName )
1205 CParserInPinImpl* This = NULL;
1208 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
1210 This = (CParserInPinImpl*)
1211 QUARTZ_AllocObj( sizeof(CParserInPinImpl) );
1213 return E_OUTOFMEMORY;
1215 QUARTZ_IUnkInit( &This->unk, NULL );
1216 This->pParser = pFilter;
1218 hr = CPinBaseImpl_InitIPin(
1220 This->unk.punkControl,
1222 &pFilter->basefilter,
1225 &inputpinhandlers );
1227 if ( SUCCEEDED(hr) )
1229 hr = CMemInputPinBaseImpl_InitIMemInputPin(
1231 This->unk.punkControl,
1235 CPinBaseImpl_UninitIPin( &This->pin );
1241 QUARTZ_FreeObj(This);
1245 This->unk.pEntries = InPinIFEntries;
1246 This->unk.dwEntries = sizeof(InPinIFEntries)/sizeof(InPinIFEntries[0]);
1247 This->unk.pOnFinalRelease = QUARTZ_DestroyParserInPin;
1251 TRACE("returned successfully.\n");
1257 /***************************************************************************
1259 * new/delete CParserOutPinImpl
1263 /* can I use offsetof safely? - FIXME? */
1264 static QUARTZ_IFEntry OutPinIFEntries[] =
1266 { &IID_IPin, offsetof(CParserOutPinImpl,pin)-offsetof(CParserOutPinImpl,unk) },
1267 { &IID_IQualityControl, offsetof(CParserOutPinImpl,qcontrol)-offsetof(CParserOutPinImpl,unk) },
1268 { &IID_IMediaSeeking, offsetof(CParserOutPinImpl,mediaseeking)-offsetof(CParserOutPinImpl,unk) },
1269 { &IID_IMediaPosition, offsetof(CParserOutPinImpl,mediaposition)-offsetof(CParserOutPinImpl,unk) },
1272 static void QUARTZ_DestroyParserOutPin(IUnknown* punk)
1274 CParserOutPinImpl_THIS(punk,unk);
1276 TRACE( "(%p)\n", This );
1278 QUARTZ_MediaType_Free( &This->m_mtOut );
1279 if ( This->m_pOutPinAllocator != NULL )
1280 IMemAllocator_Release(This->m_pOutPinAllocator);
1282 CParserOutPinImpl_UninitIMediaPosition(This);
1283 CParserOutPinImpl_UninitIMediaSeeking(This);
1284 CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
1285 CPinBaseImpl_UninitIPin( &This->pin );
1289 HRESULT QUARTZ_CreateParserOutPin(
1290 CParserImpl* pFilter,
1291 CRITICAL_SECTION* pcsPin,
1292 CParserOutPinImpl** ppPin,
1294 LPCWSTR pwszPinName )
1296 CParserOutPinImpl* This = NULL;
1299 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
1301 This = (CParserOutPinImpl*)
1302 QUARTZ_AllocObj( sizeof(CParserOutPinImpl) );
1304 return E_OUTOFMEMORY;
1306 QUARTZ_IUnkInit( &This->unk, NULL );
1307 This->pParser = pFilter;
1308 This->nStreamIndex = nStreamIndex;
1309 ZeroMemory( &This->m_mtOut, sizeof(AM_MEDIA_TYPE) );
1310 This->m_pOutPinAllocator = NULL;
1311 This->m_pUserData = NULL;
1312 This->m_bReqUsed = FALSE;
1313 This->m_pReqSample = NULL;
1314 This->m_llReqStart = 0;
1315 This->m_lReqLength = 0;
1316 This->m_rtReqStart = 0;
1317 This->m_rtReqStop = 0;
1318 This->m_dwSampleFlags = 0;
1321 hr = CPinBaseImpl_InitIPin(
1323 This->unk.punkControl,
1325 &pFilter->basefilter,
1328 &outputpinhandlers );
1330 if ( SUCCEEDED(hr) )
1332 hr = CQualityControlPassThruImpl_InitIQualityControl(
1334 This->unk.punkControl,
1336 if ( SUCCEEDED(hr) )
1338 hr = CParserOutPinImpl_InitIMediaSeeking(This);
1339 if ( SUCCEEDED(hr) )
1341 hr = CParserOutPinImpl_InitIMediaPosition(This);
1344 CParserOutPinImpl_UninitIMediaSeeking(This);
1349 CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
1354 CPinBaseImpl_UninitIPin( &This->pin );
1360 QUARTZ_FreeObj(This);
1364 This->unk.pEntries = OutPinIFEntries;
1365 This->unk.dwEntries = sizeof(OutPinIFEntries)/sizeof(OutPinIFEntries[0]);
1366 This->unk.pOnFinalRelease = QUARTZ_DestroyParserOutPin;
1370 TRACE("returned successfully.\n");
1376 /***************************************************************************
1378 * IMediaSeeking for CParserOutPinImpl
1382 static HRESULT WINAPI
1383 IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj)
1385 CParserOutPinImpl_THIS(iface,mediaseeking);
1387 TRACE("(%p)->()\n",This);
1389 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
1393 IMediaSeeking_fnAddRef(IMediaSeeking* iface)
1395 CParserOutPinImpl_THIS(iface,mediaseeking);
1397 TRACE("(%p)->()\n",This);
1399 return IUnknown_AddRef(This->unk.punkControl);
1403 IMediaSeeking_fnRelease(IMediaSeeking* iface)
1405 CParserOutPinImpl_THIS(iface,mediaseeking);
1407 TRACE("(%p)->()\n",This);
1409 return IUnknown_Release(This->unk.punkControl);
1413 static HRESULT WINAPI
1414 IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
1416 CParserOutPinImpl_THIS(iface,mediaseeking);
1417 HRESULT hr = E_NOTIMPL;
1419 TRACE("(%p)->(%p)\n",This,pdwCaps);
1421 if ( pdwCaps == NULL )
1424 EnterCriticalSection( &This->pParser->m_csParser );
1425 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
1427 FIXME("(%p)->(%p) not implemented\n",This,pdwCaps);
1431 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, pdwCaps );
1433 LeaveCriticalSection( &This->pParser->m_csParser );
1438 static HRESULT WINAPI
1439 IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
1441 CParserOutPinImpl_THIS(iface,mediaseeking);
1442 HRESULT hr = E_NOTIMPL;
1445 TRACE("(%p)->(%p)\n",This,pdwCaps);
1447 if ( pdwCaps == NULL )
1450 EnterCriticalSection( &This->pParser->m_csParser );
1451 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
1453 FIXME("(%p)->(%p) not implemented\n",This,pdwCaps);
1457 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
1458 if ( SUCCEEDED(hr) )
1461 if ( dwCaps == *pdwCaps )
1471 LeaveCriticalSection( &This->pParser->m_csParser );
1478 static HRESULT WINAPI
1479 IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat)
1481 CParserOutPinImpl_THIS(iface,mediaseeking);
1482 HRESULT hr = E_NOTIMPL;
1484 TRACE("(%p)->(%s)\n",This,debugstr_guid(pidFormat));
1486 if ( pidFormat == NULL )
1489 EnterCriticalSection( &This->pParser->m_csParser );
1490 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1492 FIXME("(%p)->(%s) not implemented\n",This,debugstr_guid(pidFormat));
1496 hr = This->pParser->m_pHandler->pIsTimeFormatSupported( This->pParser, pidFormat );
1498 LeaveCriticalSection( &This->pParser->m_csParser );
1503 static HRESULT WINAPI
1504 IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat)
1506 CParserOutPinImpl_THIS(iface,mediaseeking);
1509 TRACE("(%p)->(%p)\n",This,pidFormat);
1511 EnterCriticalSection( &This->pParser->m_csParser );
1512 hr = CParserImpl_GetPreferredTimeFormat( This->pParser, pidFormat );
1513 LeaveCriticalSection( &This->pParser->m_csParser );
1518 static HRESULT WINAPI
1519 IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat)
1521 CParserOutPinImpl_THIS(iface,mediaseeking);
1522 HRESULT hr = E_NOTIMPL;
1524 TRACE("(%p)->(%p)\n",This,pidFormat);
1526 if ( pidFormat == NULL )
1529 EnterCriticalSection( &This->pParser->m_csParser );
1530 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1532 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1536 memcpy( pidFormat, &This->pParser->m_guidTimeFormat, sizeof(GUID) );
1538 LeaveCriticalSection( &This->pParser->m_csParser );
1543 static HRESULT WINAPI
1544 IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
1546 CParserOutPinImpl_THIS(iface,mediaseeking);
1547 HRESULT hr = E_NOTIMPL;
1549 TRACE("(%p)->(%p)\n",This,pidFormat);
1551 if ( pidFormat == NULL )
1554 EnterCriticalSection( &This->pParser->m_csParser );
1555 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1557 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1561 hr = IsEqualGUID( pidFormat, &This->pParser->m_guidTimeFormat ) ? S_OK : S_FALSE;
1563 LeaveCriticalSection( &This->pParser->m_csParser );
1568 static HRESULT WINAPI
1569 IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
1571 CParserOutPinImpl_THIS(iface,mediaseeking);
1572 HRESULT hr = E_NOTIMPL;
1574 TRACE("(%p)->(%p)\n",This,pidFormat);
1576 if ( pidFormat == NULL )
1579 EnterCriticalSection( &This->pParser->m_csParser );
1580 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1582 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1586 if ( This->pParser->m_pHandler->pIsTimeFormatSupported( This->pParser, pidFormat ) == S_OK )
1588 memcpy( &This->pParser->m_guidTimeFormat, pidFormat, sizeof(GUID) );
1591 LeaveCriticalSection( &This->pParser->m_csParser );
1596 static HRESULT WINAPI
1597 IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
1599 CParserOutPinImpl_THIS(iface,mediaseeking);
1600 HRESULT hr = E_NOTIMPL;
1602 TRACE("(%p)->(%p)\n",This,pllDuration);
1604 if ( pllDuration == NULL )
1607 EnterCriticalSection( &This->pParser->m_csParser );
1608 if ( This->pParser->m_pHandler->pGetDuration == NULL )
1610 FIXME("(%p)->(%p) not implemented\n",This,pllDuration);
1614 hr = This->pParser->m_pHandler->pGetDuration( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllDuration );
1616 LeaveCriticalSection( &This->pParser->m_csParser );
1621 static HRESULT WINAPI
1622 IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos)
1624 CParserOutPinImpl_THIS(iface,mediaseeking);
1625 HRESULT hr = E_NOTIMPL;
1627 TRACE("(%p)->(%p)\n",This,pllPos);
1629 if ( pllPos == NULL )
1632 EnterCriticalSection( &This->pParser->m_csParser );
1633 if ( This->pParser->m_pHandler->pGetStopPos == NULL )
1635 FIXME("(%p)->(%p) not implemented\n",This,pllPos);
1639 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllPos );
1641 LeaveCriticalSection( &This->pParser->m_csParser );
1646 static HRESULT WINAPI
1647 IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos)
1649 CParserOutPinImpl_THIS(iface,mediaseeking);
1650 HRESULT hr = E_NOTIMPL;
1652 TRACE("(%p)->(%p)\n",This,pllPos);
1654 if ( pllPos == NULL )
1657 EnterCriticalSection( &This->pParser->m_csParser );
1658 if ( This->pParser->m_pHandler->pGetCurPos == NULL )
1660 FIXME("(%p)->(%p) not implemented\n",This,pllPos);
1664 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllPos );
1666 LeaveCriticalSection( &This->pParser->m_csParser );
1671 static HRESULT WINAPI
1672 IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn)
1674 CParserOutPinImpl_THIS(iface,mediaseeking);
1676 FIXME("(%p)->() stub!\n",This);
1681 static HRESULT WINAPI
1682 IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags)
1684 CParserOutPinImpl_THIS(iface,mediaseeking);
1686 FIXME("(%p)->() stub!\n",This);
1691 static HRESULT WINAPI
1692 IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop)
1694 CParserOutPinImpl_THIS(iface,mediaseeking);
1695 HRESULT hr = E_NOTIMPL;
1697 TRACE("(%p)->(%p,%p)\n",This,pllCur,pllStop);
1699 if ( pllCur == NULL || pllStop == NULL )
1702 EnterCriticalSection( &This->pParser->m_csParser );
1703 if ( This->pParser->m_pHandler->pGetCurPos == NULL ||
1704 This->pParser->m_pHandler->pGetStopPos == NULL )
1706 FIXME("(%p)->(%p,%p) not implemented\n",This,pllCur,pllStop);
1710 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllCur );
1711 if ( SUCCEEDED(hr) )
1712 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllStop );
1714 LeaveCriticalSection( &This->pParser->m_csParser );
1719 static HRESULT WINAPI
1720 IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast)
1722 CParserOutPinImpl_THIS(iface,mediaseeking);
1724 FIXME("(%p)->() stub!\n",This);
1729 static HRESULT WINAPI
1730 IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate)
1732 CParserOutPinImpl_THIS(iface,mediaseeking);
1734 FIXME("(%p)->() stub!\n",This);
1739 static HRESULT WINAPI
1740 IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate)
1742 CParserOutPinImpl_THIS(iface,mediaseeking);
1744 FIXME("(%p)->() stub!\n",This);
1749 static HRESULT WINAPI
1750 IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll)
1752 CParserOutPinImpl_THIS(iface,mediaseeking);
1754 FIXME("(%p)->() stub!\n",This);
1762 static ICOM_VTABLE(IMediaSeeking) imediaseeking =
1764 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1765 /* IUnknown fields */
1766 IMediaSeeking_fnQueryInterface,
1767 IMediaSeeking_fnAddRef,
1768 IMediaSeeking_fnRelease,
1769 /* IMediaSeeking fields */
1770 IMediaSeeking_fnGetCapabilities,
1771 IMediaSeeking_fnCheckCapabilities,
1772 IMediaSeeking_fnIsFormatSupported,
1773 IMediaSeeking_fnQueryPreferredFormat,
1774 IMediaSeeking_fnGetTimeFormat,
1775 IMediaSeeking_fnIsUsingTimeFormat,
1776 IMediaSeeking_fnSetTimeFormat,
1777 IMediaSeeking_fnGetDuration,
1778 IMediaSeeking_fnGetStopPosition,
1779 IMediaSeeking_fnGetCurrentPosition,
1780 IMediaSeeking_fnConvertTimeFormat,
1781 IMediaSeeking_fnSetPositions,
1782 IMediaSeeking_fnGetPositions,
1783 IMediaSeeking_fnGetAvailable,
1784 IMediaSeeking_fnSetRate,
1785 IMediaSeeking_fnGetRate,
1786 IMediaSeeking_fnGetPreroll,
1789 HRESULT CParserOutPinImpl_InitIMediaSeeking( CParserOutPinImpl* This )
1791 TRACE("(%p)\n",This);
1792 ICOM_VTBL(&This->mediaseeking) = &imediaseeking;
1797 void CParserOutPinImpl_UninitIMediaSeeking( CParserOutPinImpl* This )
1799 TRACE("(%p)\n",This);
1802 /***************************************************************************
1804 * IMediaPosition for CParserOutPinImpl
1808 static HRESULT WINAPI
1809 IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj)
1811 CParserOutPinImpl_THIS(iface,mediaposition);
1813 TRACE("(%p)->()\n",This);
1815 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
1819 IMediaPosition_fnAddRef(IMediaPosition* iface)
1821 CParserOutPinImpl_THIS(iface,mediaposition);
1823 TRACE("(%p)->()\n",This);
1825 return IUnknown_AddRef(This->unk.punkControl);
1829 IMediaPosition_fnRelease(IMediaPosition* iface)
1831 CParserOutPinImpl_THIS(iface,mediaposition);
1833 TRACE("(%p)->()\n",This);
1835 return IUnknown_Release(This->unk.punkControl);
1838 static HRESULT WINAPI
1839 IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo)
1841 CParserOutPinImpl_THIS(iface,mediaposition);
1843 FIXME("(%p)->() stub!\n",This);
1848 static HRESULT WINAPI
1849 IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
1851 CParserOutPinImpl_THIS(iface,mediaposition);
1853 FIXME("(%p)->() stub!\n",This);
1858 static HRESULT WINAPI
1859 IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
1861 CParserOutPinImpl_THIS(iface,mediaposition);
1863 FIXME("(%p)->() stub!\n",This);
1868 static HRESULT WINAPI
1869 IMediaPosition_fnInvoke(IMediaPosition* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1871 CParserOutPinImpl_THIS(iface,mediaposition);
1873 FIXME("(%p)->() stub!\n",This);
1879 static HRESULT WINAPI
1880 IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
1882 CParserOutPinImpl_THIS(iface,mediaposition);
1883 HRESULT hr = E_NOTIMPL;
1886 TRACE("(%p)->(%p)\n",This,prefTime);
1888 if ( prefTime == NULL )
1891 EnterCriticalSection( &This->pParser->m_csParser );
1892 if ( This->pParser->m_pHandler->pGetDuration == NULL )
1894 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1898 hr = This->pParser->m_pHandler->pGetDuration( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1899 if ( SUCCEEDED(hr) )
1900 *prefTime = (REFTIME)llPos;
1902 LeaveCriticalSection( &This->pParser->m_csParser );
1907 static HRESULT WINAPI
1908 IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
1910 CParserOutPinImpl_THIS(iface,mediaposition);
1911 HRESULT hr = E_NOTIMPL;
1914 FIXME("(%p)->() stub!\n",This);
1917 EnterCriticalSection( &This->pParser->m_csParser );
1918 if ( This->pParser->m_pHandler->pSetCurPos == NULL )
1920 FIXME("(%p)->() not implemented\n",This);
1924 llPos = (LONGLONG)refTime;
1925 hr = This->pParser->m_pHandler->pSetCurPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, llPos );
1926 /* FIXME - flush all streams. */
1928 LeaveCriticalSection( &This->pParser->m_csParser );
1934 static HRESULT WINAPI
1935 IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
1937 CParserOutPinImpl_THIS(iface,mediaposition);
1938 HRESULT hr = E_NOTIMPL;
1941 TRACE("(%p)->(%p)\n",This,prefTime);
1943 if ( prefTime == NULL )
1946 EnterCriticalSection( &This->pParser->m_csParser );
1947 if ( This->pParser->m_pHandler->pGetCurPos == NULL )
1949 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1953 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1954 if ( SUCCEEDED(hr) )
1955 *prefTime = (REFTIME)llPos;
1957 LeaveCriticalSection( &This->pParser->m_csParser );
1962 static HRESULT WINAPI
1963 IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
1965 CParserOutPinImpl_THIS(iface,mediaposition);
1966 HRESULT hr = E_NOTIMPL;
1969 TRACE("(%p)->(%p)\n",This,prefTime);
1971 if ( prefTime == NULL )
1974 EnterCriticalSection( &This->pParser->m_csParser );
1975 if ( This->pParser->m_pHandler->pGetStopPos == NULL )
1977 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1981 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1982 if ( SUCCEEDED(hr) )
1983 *prefTime = (REFTIME)llPos;
1985 LeaveCriticalSection( &This->pParser->m_csParser );
1990 static HRESULT WINAPI
1991 IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
1993 CParserOutPinImpl_THIS(iface,mediaposition);
1994 HRESULT hr = E_NOTIMPL;
1997 TRACE("(%p)->()\n",This);
1999 EnterCriticalSection( &This->pParser->m_csParser );
2000 if ( This->pParser->m_pHandler->pSetStopPos == NULL )
2002 FIXME("(%p)->() not implemented\n",This);
2006 llPos = (LONGLONG)refTime;
2007 hr = This->pParser->m_pHandler->pSetStopPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, llPos );
2009 LeaveCriticalSection( &This->pParser->m_csParser );
2014 static HRESULT WINAPI
2015 IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
2017 CParserOutPinImpl_THIS(iface,mediaposition);
2019 FIXME("(%p)->() stub!\n",This);
2024 static HRESULT WINAPI
2025 IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
2027 CParserOutPinImpl_THIS(iface,mediaposition);
2029 FIXME("(%p)->() stub!\n",This);
2034 static HRESULT WINAPI
2035 IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
2037 CParserOutPinImpl_THIS(iface,mediaposition);
2039 return IMediaSeeking_SetRate(CParserOutPinImpl_IMediaSeeking(This),dblRate);
2042 static HRESULT WINAPI
2043 IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
2045 CParserOutPinImpl_THIS(iface,mediaposition);
2047 return IMediaSeeking_GetRate(CParserOutPinImpl_IMediaSeeking(This),pdblRate);
2050 static HRESULT WINAPI
2051 IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
2053 CParserOutPinImpl_THIS(iface,mediaposition);
2054 HRESULT hr = E_NOTIMPL;
2057 TRACE("(%p)->(%p)\n",This,pCanSeek);
2059 if ( pCanSeek == NULL )
2062 EnterCriticalSection( &This->pParser->m_csParser );
2063 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
2065 FIXME("(%p)->(%p) not implemented\n",This,pCanSeek);
2069 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
2070 if ( SUCCEEDED(hr) )
2072 *pCanSeek = (dwCaps & AM_SEEKING_CanSeekForwards) ? OATRUE : OAFALSE;
2076 LeaveCriticalSection( &This->pParser->m_csParser );
2081 static HRESULT WINAPI
2082 IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
2084 CParserOutPinImpl_THIS(iface,mediaposition);
2085 HRESULT hr = E_NOTIMPL;
2088 TRACE("(%p)->(%p)\n",This,pCanSeek);
2090 if ( pCanSeek == NULL )
2093 EnterCriticalSection( &This->pParser->m_csParser );
2094 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
2096 FIXME("(%p)->(%p) not implemented\n",This,pCanSeek);
2100 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
2101 if ( SUCCEEDED(hr) )
2103 *pCanSeek = (dwCaps & AM_SEEKING_CanSeekBackwards) ? OATRUE : OAFALSE;
2107 LeaveCriticalSection( &This->pParser->m_csParser );
2113 static ICOM_VTABLE(IMediaPosition) imediaposition =
2115 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2116 /* IUnknown fields */
2117 IMediaPosition_fnQueryInterface,
2118 IMediaPosition_fnAddRef,
2119 IMediaPosition_fnRelease,
2120 /* IDispatch fields */
2121 IMediaPosition_fnGetTypeInfoCount,
2122 IMediaPosition_fnGetTypeInfo,
2123 IMediaPosition_fnGetIDsOfNames,
2124 IMediaPosition_fnInvoke,
2125 /* IMediaPosition fields */
2126 IMediaPosition_fnget_Duration,
2127 IMediaPosition_fnput_CurrentPosition,
2128 IMediaPosition_fnget_CurrentPosition,
2129 IMediaPosition_fnget_StopTime,
2130 IMediaPosition_fnput_StopTime,
2131 IMediaPosition_fnget_PrerollTime,
2132 IMediaPosition_fnput_PrerollTime,
2133 IMediaPosition_fnput_Rate,
2134 IMediaPosition_fnget_Rate,
2135 IMediaPosition_fnCanSeekForward,
2136 IMediaPosition_fnCanSeekBackward,
2140 HRESULT CParserOutPinImpl_InitIMediaPosition( CParserOutPinImpl* This )
2142 TRACE("(%p)\n",This);
2143 ICOM_VTBL(&This->mediaposition) = &imediaposition;
2148 void CParserOutPinImpl_UninitIMediaPosition( CParserOutPinImpl* This )
2150 TRACE("(%p)\n",This);