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_hEventInit != (HANDLE)NULL &&
572 This->m_hThread != (HANDLE)NULL )
575 This->m_hEventInit = CreateEventA(NULL,TRUE,FALSE,NULL);
576 if ( This->m_hEventInit == (HANDLE)NULL )
577 return E_OUTOFMEMORY;
579 /* create the processing thread. */
580 This->m_hThread = CreateThread(
582 CParserImplThread_Entry,
584 0, &This->m_dwThreadId );
585 if ( This->m_hThread == (HANDLE)NULL )
587 CloseHandle( This->m_hEventInit );
588 This->m_hEventInit = (HANDLE)NULL;
592 hEvents[0] = This->m_hEventInit;
593 hEvents[1] = This->m_hThread;
595 dwRes = WaitForMultipleObjects(2,hEvents,FALSE,INFINITE);
597 ResetEvent( This->m_hEventInit );
598 CloseHandle( This->m_hThread );
599 This->m_hThread = (HANDLE)NULL;
601 if ( dwRes != WAIT_OBJECT_0 )
608 BOOL CParserImpl_EndThread( CParserImpl* This, BOOL bAsync )
612 TRACE("(%p)\n",This);
613 dwThreadId = This->m_dwThreadId;
614 if ( This->m_hEventInit != (HANDLE)NULL )
616 if ( dwThreadId != 0 ) /* FIXME? */
618 dwThreadId, QUARTZ_MSG_EXITTHREAD, 0, 0 );
622 WaitForSingleObject( This->m_hEventInit, INFINITE );
623 CloseHandle( This->m_hEventInit );
624 This->m_hEventInit = (HANDLE)NULL;
631 HRESULT CParserImpl_MemCommit( CParserImpl* This )
635 IMemAllocator* pAlloc;
637 TRACE("(%p)\n",This);
639 if ( This->m_pAllocator == NULL )
642 hr = IMemAllocator_Commit( This->m_pAllocator );
646 if ( This->m_ppOutPins != NULL && This->m_cOutStreams > 0 )
648 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
650 pAlloc = This->m_ppOutPins[nIndex]->m_pOutPinAllocator;
651 if ( pAlloc != NULL && pAlloc != This->m_pAllocator )
653 hr = IMemAllocator_Commit( pAlloc );
664 HRESULT CParserImpl_GetPreferredTimeFormat( CParserImpl* This, GUID* pguidFormat )
666 static const GUID* tryformats[] =
668 &TIME_FORMAT_MEDIA_TIME,
677 if ( This->m_pHandler->pIsTimeFormatSupported == NULL )
681 while ( tryformats[n] != NULL )
683 if ( This->m_pHandler->pIsTimeFormatSupported( This, tryformats[n] ) == S_OK )
685 memcpy( pguidFormat, tryformats[n], sizeof(GUID) );
696 /***************************************************************************
698 * CParserImpl methods
702 static HRESULT CParserImpl_OnActive( CBaseFilterImpl* pImpl )
704 CParserImpl_THIS(pImpl,basefilter);
706 TRACE( "(%p)\n", This );
708 if ( !CParserImpl_OutPinsAreConnected(This) )
714 static HRESULT CParserImpl_OnInactive( CBaseFilterImpl* pImpl )
716 CParserImpl_THIS(pImpl,basefilter);
719 TRACE( "(%p)\n", This );
721 if ( !CParserImpl_OutPinsAreConnected(This) )
724 hr = CParserImpl_MemCommit(This);
727 hr = CParserImpl_BeginThread(This);
730 CParserImpl_EndThread(This,FALSE);
737 static HRESULT CParserImpl_OnStop( CBaseFilterImpl* pImpl )
739 CParserImpl_THIS(pImpl,basefilter);
741 FIXME( "(%p)\n", This );
743 This->basefilter.bIntermediateState = TRUE;
744 if ( !CParserImpl_EndThread(This,TRUE) )
745 return VFW_S_STATE_INTERMEDIATE;
747 This->basefilter.bIntermediateState = FALSE;
752 static const CBaseFilterHandlers filterhandlers =
754 CParserImpl_OnActive, /* pOnActive */
755 CParserImpl_OnInactive, /* pOnInactive */
756 CParserImpl_OnStop, /* pOnStop */
760 /***************************************************************************
762 * CParserInPinImpl methods
766 static HRESULT CParserInPinImpl_OnPreConnect( CPinBaseImpl* pImpl, IPin* pPin )
768 CParserInPinImpl_THIS(pImpl,pin);
772 IAsyncReader* pReader = NULL;
773 LPCWSTR pwszOutPinName;
774 IMemAllocator* pAllocActual;
777 TRACE("(%p,%p)\n",This,pPin);
779 if ( This->pParser->m_pHandler->pInitParser == NULL ||
780 This->pParser->m_pHandler->pUninitParser == NULL ||
781 This->pParser->m_pHandler->pGetOutPinName == NULL ||
782 This->pParser->m_pHandler->pGetStreamType == NULL ||
783 This->pParser->m_pHandler->pCheckStreamType == NULL ||
784 This->pParser->m_pHandler->pGetAllocProp == NULL ||
785 This->pParser->m_pHandler->pGetNextRequest == NULL )
787 FIXME("this parser is not implemented.\n");
791 /* at first, release all output pins. */
792 if ( CParserImpl_OutPinsAreConnected(This->pParser) )
794 CParserImpl_ReleaseListOfOutPins(This->pParser);
795 CParserImpl_ReleaseOutPins(This->pParser);
797 CParserImpl_SetAsyncReader( This->pParser, NULL );
798 hr = IPin_QueryInterface( pPin, &IID_IAsyncReader, (void**)&pReader );
801 CParserImpl_SetAsyncReader( This->pParser, pReader );
802 IAsyncReader_Release(pReader);
804 /* initialize parser. */
805 hr = This->pParser->m_pHandler->pInitParser(This->pParser,&This->pParser->m_cOutStreams);
808 This->pParser->m_ppOutPins = (CParserOutPinImpl**)QUARTZ_AllocMem(
809 sizeof(CParserOutPinImpl*) * This->pParser->m_cOutStreams );
810 if ( This->pParser->m_ppOutPins == NULL )
811 return E_OUTOFMEMORY;
812 for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
813 This->pParser->m_ppOutPins[nIndex] = NULL;
815 /* create and initialize an allocator. */
816 hr = This->pParser->m_pHandler->pGetAllocProp(This->pParser,&This->pParser->m_propAlloc);
819 if ( This->pParser->m_propAlloc.cbAlign == 0 )
820 This->pParser->m_propAlloc.cbAlign = 1;
822 if ( This->pParser->m_pAllocator == NULL )
824 hr = QUARTZ_CreateMemoryAllocator(NULL,(void**)&punk);
827 hr = IUnknown_QueryInterface( punk, &IID_IMemAllocator, (void**)&This->pParser->m_pAllocator );
828 IUnknown_Release(punk);
833 hr = IAsyncReader_RequestAllocator(pReader,This->pParser->m_pAllocator,&This->pParser->m_propAlloc,&pAllocActual);
836 IMemAllocator_Release(This->pParser->m_pAllocator);
837 This->pParser->m_pAllocator = pAllocActual;
839 /* create output pins. */
840 for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
842 pwszOutPinName = This->pParser->m_pHandler->pGetOutPinName(This->pParser,nIndex);
843 if ( pwszOutPinName == NULL )
845 hr = QUARTZ_CreateParserOutPin(
847 &This->pParser->m_csParser,
848 &This->pParser->m_ppOutPins[nIndex],
849 nIndex, pwszOutPinName );
851 hr = QUARTZ_CompList_AddTailComp(
852 This->pParser->basefilter.pOutPins,
853 (IUnknown*)&(This->pParser->m_ppOutPins[nIndex]->pin),
857 pmt = &This->pParser->m_ppOutPins[nIndex]->m_mtOut;
858 QUARTZ_MediaType_Free( pmt );
859 ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
860 hr = This->pParser->m_pHandler->pGetStreamType(This->pParser,nIndex,pmt);
863 ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
866 This->pParser->m_ppOutPins[nIndex]->pin.cAcceptTypes = 1;
867 This->pParser->m_ppOutPins[nIndex]->pin.pmtAcceptTypes = pmt;
873 static HRESULT CParserInPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
875 CParserInPinImpl_THIS(pImpl,pin);
877 /* assume the graph is already stopped */
878 /*CParserImpl_OnInactive(&This->pParser->basefilter);*/
879 /*CParserImpl_OnStop(&This->pParser->basefilter);*/
880 if ( This->pParser->m_pHandler->pUninitParser != NULL )
881 This->pParser->m_pHandler->pUninitParser(This->pParser);
882 CParserImpl_SetAsyncReader( This->pParser, NULL );
883 if ( This->pParser->m_pAllocator != NULL )
885 IMemAllocator_Decommit(This->pParser->m_pAllocator);
886 IMemAllocator_Release(This->pParser->m_pAllocator);
887 This->pParser->m_pAllocator = NULL;
893 static HRESULT CParserInPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
895 CParserInPinImpl_THIS(pImpl,pin);
897 TRACE("(%p,%p)\n",This,pmt);
899 if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Stream ) )
905 static const CBasePinHandlers inputpinhandlers =
907 CParserInPinImpl_OnPreConnect, /* pOnPreConnect */
908 NULL, /* pOnPostConnect */
909 CParserInPinImpl_OnDisconnect, /* pOnDisconnect */
910 CParserInPinImpl_CheckMediaType, /* pCheckMediaType */
911 NULL, /* pQualityNotify */
913 NULL, /* pReceiveCanBlock */
914 NULL, /* pEndOfStream */
915 NULL, /* pBeginFlush */
916 NULL, /* pEndFlush */
917 NULL, /* pNewSegment */
920 /***************************************************************************
922 * CParserOutPinImpl methods
926 static HRESULT CParserOutPinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPin )
928 CParserOutPinImpl_THIS(pImpl,pin);
929 ALLOCATOR_PROPERTIES propReq;
930 ALLOCATOR_PROPERTIES propActual;
931 IMemAllocator* pAllocator;
933 BOOL bNewAllocator = FALSE;
935 TRACE("(%p,%p)\n",This,pPin);
937 if ( This->pin.pMemInputPinConnectedTo == NULL )
940 if ( This->m_pOutPinAllocator != NULL )
942 IMemAllocator_Release(This->m_pOutPinAllocator);
943 This->m_pOutPinAllocator = NULL;
946 /* try to use This->pParser->m_pAllocator. */
947 ZeroMemory( &propReq, sizeof(ALLOCATOR_PROPERTIES) );
948 hr = IMemInputPin_GetAllocatorRequirements(
949 This->pin.pMemInputPinConnectedTo, &propReq );
950 if ( propReq.cbAlign != 0 )
952 if ( This->pParser->m_propAlloc.cbAlign != ( This->pParser->m_propAlloc.cbAlign / propReq.cbAlign * propReq.cbAlign ) )
953 bNewAllocator = TRUE;
955 if ( propReq.cbPrefix != 0 )
956 bNewAllocator = TRUE;
957 if ( !bNewAllocator )
959 hr = IMemInputPin_NotifyAllocator(
960 This->pin.pMemInputPinConnectedTo,
961 This->pParser->m_pAllocator, FALSE );
964 This->m_pOutPinAllocator = This->pParser->m_pAllocator;
965 IMemAllocator_AddRef(This->m_pOutPinAllocator);
970 hr = IMemInputPin_GetAllocator(
971 This->pin.pMemInputPinConnectedTo, &pAllocator );
974 hr = IMemAllocator_SetProperties( pAllocator, &This->pParser->m_propAlloc, &propActual );
976 hr = IMemInputPin_NotifyAllocator(
977 This->pin.pMemInputPinConnectedTo, pAllocator, FALSE );
980 IMemAllocator_Release(pAllocator);
984 This->m_pOutPinAllocator = pAllocator;
988 static HRESULT CParserOutPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
990 CParserOutPinImpl_THIS(pImpl,pin);
992 if ( This->m_pOutPinAllocator != NULL )
994 IMemAllocator_Release(This->m_pOutPinAllocator);
995 This->m_pOutPinAllocator = NULL;
1001 static HRESULT CParserOutPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
1003 CParserOutPinImpl_THIS(pImpl,pin);
1006 TRACE("(%p,%p)\n",This,pmt);
1010 if ( This->pParser->m_pHandler->pCheckStreamType == NULL )
1013 hr = This->pParser->m_pHandler->pCheckStreamType( This->pParser, This->nStreamIndex, pmt );
1021 static const CBasePinHandlers outputpinhandlers =
1023 NULL, /* pOnPreConnect */
1024 CParserOutPinImpl_OnPostConnect, /* pOnPostConnect */
1025 CParserOutPinImpl_OnDisconnect, /* pOnDisconnect */
1026 CParserOutPinImpl_CheckMediaType, /* pCheckMediaType */
1027 NULL, /* pQualityNotify */
1028 OutputPinSync_Receive, /* pReceive */
1029 OutputPinSync_ReceiveCanBlock, /* pReceiveCanBlock */
1030 OutputPinSync_EndOfStream, /* pEndOfStream */
1031 OutputPinSync_BeginFlush, /* pBeginFlush */
1032 OutputPinSync_EndFlush, /* pEndFlush */
1033 OutputPinSync_NewSegment, /* pNewSegment */
1036 /***************************************************************************
1038 * new/delete CParserImpl
1042 /* can I use offsetof safely? - FIXME? */
1043 static QUARTZ_IFEntry FilterIFEntries[] =
1045 { &IID_IPersist, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1046 { &IID_IMediaFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1047 { &IID_IBaseFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1050 static void QUARTZ_DestroyParser(IUnknown* punk)
1052 CParserImpl_THIS(punk,unk);
1054 TRACE( "(%p)\n", This );
1056 if ( This->m_pInPin != NULL )
1057 CParserInPinImpl_OnDisconnect(&This->m_pInPin->pin);
1059 CParserImpl_SetAsyncReader( This, NULL );
1060 if ( This->m_pAllocator != NULL )
1062 IMemAllocator_Release(This->m_pAllocator);
1063 This->m_pAllocator = NULL;
1065 if ( This->m_pInPin != NULL )
1067 IUnknown_Release(This->m_pInPin->unk.punkControl);
1068 This->m_pInPin = NULL;
1070 CParserImpl_ReleaseOutPins( This );
1072 DeleteCriticalSection( &This->m_csParser );
1074 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
1077 HRESULT QUARTZ_CreateParser(
1078 IUnknown* punkOuter,void** ppobj,
1079 const CLSID* pclsidParser,
1080 LPCWSTR pwszParserName,
1081 LPCWSTR pwszInPinName,
1082 const ParserHandlers* pHandler )
1084 CParserImpl* This = NULL;
1087 TRACE("(%p,%p)\n",punkOuter,ppobj);
1089 This = (CParserImpl*)
1090 QUARTZ_AllocObj( sizeof(CParserImpl) );
1092 return E_OUTOFMEMORY;
1093 ZeroMemory( This, sizeof(CParserImpl) );
1095 This->m_pInPin = NULL;
1096 This->m_cOutStreams = 0;
1097 This->m_ppOutPins = NULL;
1098 memcpy( &This->m_guidTimeFormat, &TIME_FORMAT_NONE, sizeof(GUID) );
1099 This->m_pReader = NULL;
1100 This->m_pAllocator = NULL;
1101 ZeroMemory( &This->m_propAlloc, sizeof(ALLOCATOR_PROPERTIES) );
1102 This->m_hEventInit = (HANDLE)NULL;
1103 This->m_hThread = (HANDLE)NULL;
1104 This->m_dwThreadId = 0;
1105 This->m_bSendEOS = FALSE;
1106 This->m_pHandler = pHandler;
1107 This->m_pUserData = NULL;
1109 QUARTZ_IUnkInit( &This->unk, punkOuter );
1111 hr = CBaseFilterImpl_InitIBaseFilter(
1113 This->unk.punkControl,
1117 if ( SUCCEEDED(hr) )
1119 /* construct this class. */
1124 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
1130 QUARTZ_FreeObj(This);
1134 This->unk.pEntries = FilterIFEntries;
1135 This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
1136 This->unk.pOnFinalRelease = QUARTZ_DestroyParser;
1137 InitializeCriticalSection( &This->m_csParser );
1139 /* create the input pin. */
1140 hr = QUARTZ_CreateParserInPin(
1145 if ( SUCCEEDED(hr) )
1146 hr = QUARTZ_CompList_AddComp(
1147 This->basefilter.pInPins,
1148 (IUnknown*)&(This->m_pInPin->pin),
1153 IUnknown_Release( This->unk.punkControl );
1157 *ppobj = (void*)&(This->unk);
1159 (void)CParserImpl_GetPreferredTimeFormat( This, &This->m_guidTimeFormat );
1164 /***************************************************************************
1166 * new/delete CParserInPinImpl
1170 /* can I use offsetof safely? - FIXME? */
1171 static QUARTZ_IFEntry InPinIFEntries[] =
1173 { &IID_IPin, offsetof(CParserInPinImpl,pin)-offsetof(CParserInPinImpl,unk) },
1174 { &IID_IMemInputPin, offsetof(CParserInPinImpl,meminput)-offsetof(CParserInPinImpl,unk) },
1177 static void QUARTZ_DestroyParserInPin(IUnknown* punk)
1179 CParserInPinImpl_THIS(punk,unk);
1181 TRACE( "(%p)\n", This );
1183 CPinBaseImpl_UninitIPin( &This->pin );
1184 CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
1187 HRESULT QUARTZ_CreateParserInPin(
1188 CParserImpl* pFilter,
1189 CRITICAL_SECTION* pcsPin,
1190 CParserInPinImpl** ppPin,
1191 LPCWSTR pwszPinName )
1193 CParserInPinImpl* This = NULL;
1196 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
1198 This = (CParserInPinImpl*)
1199 QUARTZ_AllocObj( sizeof(CParserInPinImpl) );
1201 return E_OUTOFMEMORY;
1203 QUARTZ_IUnkInit( &This->unk, NULL );
1204 This->pParser = pFilter;
1206 hr = CPinBaseImpl_InitIPin(
1208 This->unk.punkControl,
1210 &pFilter->basefilter,
1213 &inputpinhandlers );
1215 if ( SUCCEEDED(hr) )
1217 hr = CMemInputPinBaseImpl_InitIMemInputPin(
1219 This->unk.punkControl,
1223 CPinBaseImpl_UninitIPin( &This->pin );
1229 QUARTZ_FreeObj(This);
1233 This->unk.pEntries = InPinIFEntries;
1234 This->unk.dwEntries = sizeof(InPinIFEntries)/sizeof(InPinIFEntries[0]);
1235 This->unk.pOnFinalRelease = QUARTZ_DestroyParserInPin;
1239 TRACE("returned successfully.\n");
1245 /***************************************************************************
1247 * new/delete CParserOutPinImpl
1251 /* can I use offsetof safely? - FIXME? */
1252 static QUARTZ_IFEntry OutPinIFEntries[] =
1254 { &IID_IPin, offsetof(CParserOutPinImpl,pin)-offsetof(CParserOutPinImpl,unk) },
1255 { &IID_IQualityControl, offsetof(CParserOutPinImpl,qcontrol)-offsetof(CParserOutPinImpl,unk) },
1256 { &IID_IMediaSeeking, offsetof(CParserOutPinImpl,mediaseeking)-offsetof(CParserOutPinImpl,unk) },
1257 { &IID_IMediaPosition, offsetof(CParserOutPinImpl,mediaposition)-offsetof(CParserOutPinImpl,unk) },
1260 static void QUARTZ_DestroyParserOutPin(IUnknown* punk)
1262 CParserOutPinImpl_THIS(punk,unk);
1264 TRACE( "(%p)\n", This );
1266 QUARTZ_MediaType_Free( &This->m_mtOut );
1267 if ( This->m_pOutPinAllocator != NULL )
1268 IMemAllocator_Release(This->m_pOutPinAllocator);
1270 CParserOutPinImpl_UninitIMediaPosition(This);
1271 CParserOutPinImpl_UninitIMediaSeeking(This);
1272 CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
1273 CPinBaseImpl_UninitIPin( &This->pin );
1277 HRESULT QUARTZ_CreateParserOutPin(
1278 CParserImpl* pFilter,
1279 CRITICAL_SECTION* pcsPin,
1280 CParserOutPinImpl** ppPin,
1282 LPCWSTR pwszPinName )
1284 CParserOutPinImpl* This = NULL;
1287 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
1289 This = (CParserOutPinImpl*)
1290 QUARTZ_AllocObj( sizeof(CParserOutPinImpl) );
1292 return E_OUTOFMEMORY;
1294 QUARTZ_IUnkInit( &This->unk, NULL );
1295 This->pParser = pFilter;
1296 This->nStreamIndex = nStreamIndex;
1297 ZeroMemory( &This->m_mtOut, sizeof(AM_MEDIA_TYPE) );
1298 This->m_pOutPinAllocator = NULL;
1299 This->m_pUserData = NULL;
1300 This->m_bReqUsed = FALSE;
1301 This->m_pReqSample = NULL;
1302 This->m_llReqStart = 0;
1303 This->m_lReqLength = 0;
1304 This->m_rtReqStart = 0;
1305 This->m_rtReqStop = 0;
1306 This->m_dwSampleFlags = 0;
1309 hr = CPinBaseImpl_InitIPin(
1311 This->unk.punkControl,
1313 &pFilter->basefilter,
1316 &outputpinhandlers );
1318 if ( SUCCEEDED(hr) )
1320 hr = CQualityControlPassThruImpl_InitIQualityControl(
1322 This->unk.punkControl,
1324 if ( SUCCEEDED(hr) )
1326 hr = CParserOutPinImpl_InitIMediaSeeking(This);
1327 if ( SUCCEEDED(hr) )
1329 hr = CParserOutPinImpl_InitIMediaPosition(This);
1332 CParserOutPinImpl_UninitIMediaSeeking(This);
1337 CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
1342 CPinBaseImpl_UninitIPin( &This->pin );
1348 QUARTZ_FreeObj(This);
1352 This->unk.pEntries = OutPinIFEntries;
1353 This->unk.dwEntries = sizeof(OutPinIFEntries)/sizeof(OutPinIFEntries[0]);
1354 This->unk.pOnFinalRelease = QUARTZ_DestroyParserOutPin;
1358 TRACE("returned successfully.\n");
1364 /***************************************************************************
1366 * IMediaSeeking for CParserOutPinImpl
1370 static HRESULT WINAPI
1371 IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj)
1373 CParserOutPinImpl_THIS(iface,mediaseeking);
1375 TRACE("(%p)->()\n",This);
1377 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
1381 IMediaSeeking_fnAddRef(IMediaSeeking* iface)
1383 CParserOutPinImpl_THIS(iface,mediaseeking);
1385 TRACE("(%p)->()\n",This);
1387 return IUnknown_AddRef(This->unk.punkControl);
1391 IMediaSeeking_fnRelease(IMediaSeeking* iface)
1393 CParserOutPinImpl_THIS(iface,mediaseeking);
1395 TRACE("(%p)->()\n",This);
1397 return IUnknown_Release(This->unk.punkControl);
1401 static HRESULT WINAPI
1402 IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
1404 CParserOutPinImpl_THIS(iface,mediaseeking);
1405 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, pdwCaps );
1421 LeaveCriticalSection( &This->pParser->m_csParser );
1426 static HRESULT WINAPI
1427 IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
1429 CParserOutPinImpl_THIS(iface,mediaseeking);
1430 HRESULT hr = E_NOTIMPL;
1433 TRACE("(%p)->(%p)\n",This,pdwCaps);
1435 if ( pdwCaps == NULL )
1438 EnterCriticalSection( &This->pParser->m_csParser );
1439 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
1441 FIXME("(%p)->(%p) not implemented\n",This,pdwCaps);
1445 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
1446 if ( SUCCEEDED(hr) )
1449 if ( dwCaps == *pdwCaps )
1459 LeaveCriticalSection( &This->pParser->m_csParser );
1466 static HRESULT WINAPI
1467 IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat)
1469 CParserOutPinImpl_THIS(iface,mediaseeking);
1470 HRESULT hr = E_NOTIMPL;
1472 TRACE("(%p)->(%s)\n",This,debugstr_guid(pidFormat));
1474 if ( pidFormat == NULL )
1477 EnterCriticalSection( &This->pParser->m_csParser );
1478 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1480 FIXME("(%p)->(%s) not implemented\n",This,debugstr_guid(pidFormat));
1484 hr = This->pParser->m_pHandler->pIsTimeFormatSupported( This->pParser, pidFormat );
1486 LeaveCriticalSection( &This->pParser->m_csParser );
1491 static HRESULT WINAPI
1492 IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat)
1494 CParserOutPinImpl_THIS(iface,mediaseeking);
1497 TRACE("(%p)->(%p)\n",This,pidFormat);
1499 EnterCriticalSection( &This->pParser->m_csParser );
1500 hr = CParserImpl_GetPreferredTimeFormat( This->pParser, pidFormat );
1501 LeaveCriticalSection( &This->pParser->m_csParser );
1506 static HRESULT WINAPI
1507 IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat)
1509 CParserOutPinImpl_THIS(iface,mediaseeking);
1510 HRESULT hr = E_NOTIMPL;
1512 TRACE("(%p)->(%p)\n",This,pidFormat);
1514 if ( pidFormat == NULL )
1517 EnterCriticalSection( &This->pParser->m_csParser );
1518 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1520 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1524 memcpy( pidFormat, &This->pParser->m_guidTimeFormat, sizeof(GUID) );
1526 LeaveCriticalSection( &This->pParser->m_csParser );
1531 static HRESULT WINAPI
1532 IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
1534 CParserOutPinImpl_THIS(iface,mediaseeking);
1535 HRESULT hr = E_NOTIMPL;
1537 TRACE("(%p)->(%p)\n",This,pidFormat);
1539 if ( pidFormat == NULL )
1542 EnterCriticalSection( &This->pParser->m_csParser );
1543 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1545 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1549 hr = IsEqualGUID( pidFormat, &This->pParser->m_guidTimeFormat ) ? S_OK : S_FALSE;
1551 LeaveCriticalSection( &This->pParser->m_csParser );
1556 static HRESULT WINAPI
1557 IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
1559 CParserOutPinImpl_THIS(iface,mediaseeking);
1560 HRESULT hr = E_NOTIMPL;
1562 TRACE("(%p)->(%p)\n",This,pidFormat);
1564 if ( pidFormat == NULL )
1567 EnterCriticalSection( &This->pParser->m_csParser );
1568 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1570 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1574 if ( This->pParser->m_pHandler->pIsTimeFormatSupported( This->pParser, pidFormat ) == S_OK )
1576 memcpy( &This->pParser->m_guidTimeFormat, pidFormat, sizeof(GUID) );
1579 LeaveCriticalSection( &This->pParser->m_csParser );
1584 static HRESULT WINAPI
1585 IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
1587 CParserOutPinImpl_THIS(iface,mediaseeking);
1588 HRESULT hr = E_NOTIMPL;
1590 TRACE("(%p)->(%p)\n",This,pllDuration);
1592 if ( pllDuration == NULL )
1595 EnterCriticalSection( &This->pParser->m_csParser );
1596 if ( This->pParser->m_pHandler->pGetDuration == NULL )
1598 FIXME("(%p)->(%p) not implemented\n",This,pllDuration);
1602 hr = This->pParser->m_pHandler->pGetDuration( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllDuration );
1604 LeaveCriticalSection( &This->pParser->m_csParser );
1609 static HRESULT WINAPI
1610 IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos)
1612 CParserOutPinImpl_THIS(iface,mediaseeking);
1613 HRESULT hr = E_NOTIMPL;
1615 TRACE("(%p)->(%p)\n",This,pllPos);
1617 if ( pllPos == NULL )
1620 EnterCriticalSection( &This->pParser->m_csParser );
1621 if ( This->pParser->m_pHandler->pGetStopPos == NULL )
1623 FIXME("(%p)->(%p) not implemented\n",This,pllPos);
1627 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllPos );
1629 LeaveCriticalSection( &This->pParser->m_csParser );
1634 static HRESULT WINAPI
1635 IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos)
1637 CParserOutPinImpl_THIS(iface,mediaseeking);
1638 HRESULT hr = E_NOTIMPL;
1640 TRACE("(%p)->(%p)\n",This,pllPos);
1642 if ( pllPos == NULL )
1645 EnterCriticalSection( &This->pParser->m_csParser );
1646 if ( This->pParser->m_pHandler->pGetCurPos == NULL )
1648 FIXME("(%p)->(%p) not implemented\n",This,pllPos);
1652 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllPos );
1654 LeaveCriticalSection( &This->pParser->m_csParser );
1659 static HRESULT WINAPI
1660 IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn)
1662 CParserOutPinImpl_THIS(iface,mediaseeking);
1664 FIXME("(%p)->() stub!\n",This);
1669 static HRESULT WINAPI
1670 IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags)
1672 CParserOutPinImpl_THIS(iface,mediaseeking);
1674 FIXME("(%p)->() stub!\n",This);
1679 static HRESULT WINAPI
1680 IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop)
1682 CParserOutPinImpl_THIS(iface,mediaseeking);
1683 HRESULT hr = E_NOTIMPL;
1685 TRACE("(%p)->(%p,%p)\n",This,pllCur,pllStop);
1687 if ( pllCur == NULL || pllStop == NULL )
1690 EnterCriticalSection( &This->pParser->m_csParser );
1691 if ( This->pParser->m_pHandler->pGetCurPos == NULL ||
1692 This->pParser->m_pHandler->pGetStopPos == NULL )
1694 FIXME("(%p)->(%p,%p) not implemented\n",This,pllCur,pllStop);
1698 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllCur );
1699 if ( SUCCEEDED(hr) )
1700 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllStop );
1702 LeaveCriticalSection( &This->pParser->m_csParser );
1707 static HRESULT WINAPI
1708 IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast)
1710 CParserOutPinImpl_THIS(iface,mediaseeking);
1712 FIXME("(%p)->() stub!\n",This);
1717 static HRESULT WINAPI
1718 IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate)
1720 CParserOutPinImpl_THIS(iface,mediaseeking);
1722 FIXME("(%p)->() stub!\n",This);
1727 static HRESULT WINAPI
1728 IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate)
1730 CParserOutPinImpl_THIS(iface,mediaseeking);
1732 FIXME("(%p)->() stub!\n",This);
1737 static HRESULT WINAPI
1738 IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll)
1740 CParserOutPinImpl_THIS(iface,mediaseeking);
1742 FIXME("(%p)->() stub!\n",This);
1750 static ICOM_VTABLE(IMediaSeeking) imediaseeking =
1752 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1753 /* IUnknown fields */
1754 IMediaSeeking_fnQueryInterface,
1755 IMediaSeeking_fnAddRef,
1756 IMediaSeeking_fnRelease,
1757 /* IMediaSeeking fields */
1758 IMediaSeeking_fnGetCapabilities,
1759 IMediaSeeking_fnCheckCapabilities,
1760 IMediaSeeking_fnIsFormatSupported,
1761 IMediaSeeking_fnQueryPreferredFormat,
1762 IMediaSeeking_fnGetTimeFormat,
1763 IMediaSeeking_fnIsUsingTimeFormat,
1764 IMediaSeeking_fnSetTimeFormat,
1765 IMediaSeeking_fnGetDuration,
1766 IMediaSeeking_fnGetStopPosition,
1767 IMediaSeeking_fnGetCurrentPosition,
1768 IMediaSeeking_fnConvertTimeFormat,
1769 IMediaSeeking_fnSetPositions,
1770 IMediaSeeking_fnGetPositions,
1771 IMediaSeeking_fnGetAvailable,
1772 IMediaSeeking_fnSetRate,
1773 IMediaSeeking_fnGetRate,
1774 IMediaSeeking_fnGetPreroll,
1777 HRESULT CParserOutPinImpl_InitIMediaSeeking( CParserOutPinImpl* This )
1779 TRACE("(%p)\n",This);
1780 ICOM_VTBL(&This->mediaseeking) = &imediaseeking;
1785 void CParserOutPinImpl_UninitIMediaSeeking( CParserOutPinImpl* This )
1787 TRACE("(%p)\n",This);
1790 /***************************************************************************
1792 * IMediaPosition for CParserOutPinImpl
1796 static HRESULT WINAPI
1797 IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj)
1799 CParserOutPinImpl_THIS(iface,mediaposition);
1801 TRACE("(%p)->()\n",This);
1803 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
1807 IMediaPosition_fnAddRef(IMediaPosition* iface)
1809 CParserOutPinImpl_THIS(iface,mediaposition);
1811 TRACE("(%p)->()\n",This);
1813 return IUnknown_AddRef(This->unk.punkControl);
1817 IMediaPosition_fnRelease(IMediaPosition* iface)
1819 CParserOutPinImpl_THIS(iface,mediaposition);
1821 TRACE("(%p)->()\n",This);
1823 return IUnknown_Release(This->unk.punkControl);
1826 static HRESULT WINAPI
1827 IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo)
1829 CParserOutPinImpl_THIS(iface,mediaposition);
1831 FIXME("(%p)->() stub!\n",This);
1836 static HRESULT WINAPI
1837 IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
1839 CParserOutPinImpl_THIS(iface,mediaposition);
1841 FIXME("(%p)->() stub!\n",This);
1846 static HRESULT WINAPI
1847 IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
1849 CParserOutPinImpl_THIS(iface,mediaposition);
1851 FIXME("(%p)->() stub!\n",This);
1856 static HRESULT WINAPI
1857 IMediaPosition_fnInvoke(IMediaPosition* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1859 CParserOutPinImpl_THIS(iface,mediaposition);
1861 FIXME("(%p)->() stub!\n",This);
1867 static HRESULT WINAPI
1868 IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
1870 CParserOutPinImpl_THIS(iface,mediaposition);
1871 HRESULT hr = E_NOTIMPL;
1874 TRACE("(%p)->(%p)\n",This,prefTime);
1876 if ( prefTime == NULL )
1879 EnterCriticalSection( &This->pParser->m_csParser );
1880 if ( This->pParser->m_pHandler->pGetDuration == NULL )
1882 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1886 hr = This->pParser->m_pHandler->pGetDuration( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1887 if ( SUCCEEDED(hr) )
1888 *prefTime = (REFTIME)llPos;
1890 LeaveCriticalSection( &This->pParser->m_csParser );
1895 static HRESULT WINAPI
1896 IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
1898 CParserOutPinImpl_THIS(iface,mediaposition);
1899 HRESULT hr = E_NOTIMPL;
1902 FIXME("(%p)->() stub!\n",This);
1905 EnterCriticalSection( &This->pParser->m_csParser );
1906 if ( This->pParser->m_pHandler->pSetCurPos == NULL )
1908 FIXME("(%p)->() not implemented\n",This);
1912 llPos = (LONGLONG)refTime;
1913 hr = This->pParser->m_pHandler->pSetCurPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, llPos );
1914 /* FIXME - flush all streams. */
1916 LeaveCriticalSection( &This->pParser->m_csParser );
1922 static HRESULT WINAPI
1923 IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
1925 CParserOutPinImpl_THIS(iface,mediaposition);
1926 HRESULT hr = E_NOTIMPL;
1929 TRACE("(%p)->(%p)\n",This,prefTime);
1931 if ( prefTime == NULL )
1934 EnterCriticalSection( &This->pParser->m_csParser );
1935 if ( This->pParser->m_pHandler->pGetCurPos == NULL )
1937 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1941 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1942 if ( SUCCEEDED(hr) )
1943 *prefTime = (REFTIME)llPos;
1945 LeaveCriticalSection( &This->pParser->m_csParser );
1950 static HRESULT WINAPI
1951 IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
1953 CParserOutPinImpl_THIS(iface,mediaposition);
1954 HRESULT hr = E_NOTIMPL;
1957 TRACE("(%p)->(%p)\n",This,prefTime);
1959 if ( prefTime == NULL )
1962 EnterCriticalSection( &This->pParser->m_csParser );
1963 if ( This->pParser->m_pHandler->pGetStopPos == NULL )
1965 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1969 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1970 if ( SUCCEEDED(hr) )
1971 *prefTime = (REFTIME)llPos;
1973 LeaveCriticalSection( &This->pParser->m_csParser );
1978 static HRESULT WINAPI
1979 IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
1981 CParserOutPinImpl_THIS(iface,mediaposition);
1982 HRESULT hr = E_NOTIMPL;
1985 TRACE("(%p)->()\n",This);
1987 EnterCriticalSection( &This->pParser->m_csParser );
1988 if ( This->pParser->m_pHandler->pSetStopPos == NULL )
1990 FIXME("(%p)->() not implemented\n",This);
1994 llPos = (LONGLONG)refTime;
1995 hr = This->pParser->m_pHandler->pSetStopPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, llPos );
1997 LeaveCriticalSection( &This->pParser->m_csParser );
2002 static HRESULT WINAPI
2003 IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
2005 CParserOutPinImpl_THIS(iface,mediaposition);
2007 FIXME("(%p)->() stub!\n",This);
2012 static HRESULT WINAPI
2013 IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
2015 CParserOutPinImpl_THIS(iface,mediaposition);
2017 FIXME("(%p)->() stub!\n",This);
2022 static HRESULT WINAPI
2023 IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
2025 CParserOutPinImpl_THIS(iface,mediaposition);
2027 return IMediaSeeking_SetRate(CParserOutPinImpl_IMediaSeeking(This),dblRate);
2030 static HRESULT WINAPI
2031 IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
2033 CParserOutPinImpl_THIS(iface,mediaposition);
2035 return IMediaSeeking_GetRate(CParserOutPinImpl_IMediaSeeking(This),pdblRate);
2038 static HRESULT WINAPI
2039 IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
2041 CParserOutPinImpl_THIS(iface,mediaposition);
2042 HRESULT hr = E_NOTIMPL;
2045 TRACE("(%p)->(%p)\n",This,pCanSeek);
2047 if ( pCanSeek == NULL )
2050 EnterCriticalSection( &This->pParser->m_csParser );
2051 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
2053 FIXME("(%p)->(%p) not implemented\n",This,pCanSeek);
2057 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
2058 if ( SUCCEEDED(hr) )
2060 *pCanSeek = (dwCaps & AM_SEEKING_CanSeekForwards) ? OATRUE : OAFALSE;
2064 LeaveCriticalSection( &This->pParser->m_csParser );
2069 static HRESULT WINAPI
2070 IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
2072 CParserOutPinImpl_THIS(iface,mediaposition);
2073 HRESULT hr = E_NOTIMPL;
2076 TRACE("(%p)->(%p)\n",This,pCanSeek);
2078 if ( pCanSeek == NULL )
2081 EnterCriticalSection( &This->pParser->m_csParser );
2082 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
2084 FIXME("(%p)->(%p) not implemented\n",This,pCanSeek);
2088 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
2089 if ( SUCCEEDED(hr) )
2091 *pCanSeek = (dwCaps & AM_SEEKING_CanSeekBackwards) ? OATRUE : OAFALSE;
2095 LeaveCriticalSection( &This->pParser->m_csParser );
2101 static ICOM_VTABLE(IMediaPosition) imediaposition =
2103 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2104 /* IUnknown fields */
2105 IMediaPosition_fnQueryInterface,
2106 IMediaPosition_fnAddRef,
2107 IMediaPosition_fnRelease,
2108 /* IDispatch fields */
2109 IMediaPosition_fnGetTypeInfoCount,
2110 IMediaPosition_fnGetTypeInfo,
2111 IMediaPosition_fnGetIDsOfNames,
2112 IMediaPosition_fnInvoke,
2113 /* IMediaPosition fields */
2114 IMediaPosition_fnget_Duration,
2115 IMediaPosition_fnput_CurrentPosition,
2116 IMediaPosition_fnget_CurrentPosition,
2117 IMediaPosition_fnget_StopTime,
2118 IMediaPosition_fnput_StopTime,
2119 IMediaPosition_fnget_PrerollTime,
2120 IMediaPosition_fnput_PrerollTime,
2121 IMediaPosition_fnput_Rate,
2122 IMediaPosition_fnget_Rate,
2123 IMediaPosition_fnCanSeekForward,
2124 IMediaPosition_fnCanSeekBackward,
2128 HRESULT CParserOutPinImpl_InitIMediaPosition( CParserOutPinImpl* This )
2130 TRACE("(%p)\n",This);
2131 ICOM_VTBL(&This->mediaposition) = &imediaposition;
2136 void CParserOutPinImpl_UninitIMediaPosition( CParserOutPinImpl* This )
2138 TRACE("(%p)\n",This);