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 */
471 /***************************************************************************
473 * CParserImpl internal methods
478 void CParserImpl_SetAsyncReader( CParserImpl* This, IAsyncReader* pReader )
480 if ( This->m_pReader != NULL )
482 IAsyncReader_Release( This->m_pReader );
483 This->m_pReader = NULL;
485 if ( pReader != NULL )
487 This->m_pReader = pReader;
488 IAsyncReader_AddRef(This->m_pReader);
493 void CParserImpl_ReleaseOutPins( CParserImpl* This )
497 if ( This->m_ppOutPins != NULL )
499 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
501 if ( This->m_ppOutPins[nIndex] != NULL )
503 IUnknown_Release(This->m_ppOutPins[nIndex]->unk.punkControl);
504 This->m_ppOutPins[nIndex] = NULL;
507 QUARTZ_FreeMem(This->m_ppOutPins);
508 This->m_ppOutPins = NULL;
510 This->m_cOutStreams = 0;
514 BOOL CParserImpl_OutPinsAreConnected( CParserImpl* This )
516 QUARTZ_CompListItem* pItem;
521 QUARTZ_CompList_Lock( This->basefilter.pOutPins );
522 pItem = QUARTZ_CompList_GetFirst( This->basefilter.pOutPins );
523 while ( pItem != NULL )
527 pPin = (IPin*)QUARTZ_CompList_GetItemPtr(pItem);
529 hr = IPin_ConnectedTo(pPin,&pPinPeer);
530 if ( hr == S_OK && pPinPeer != NULL )
532 IPin_Release(pPinPeer);
535 pItem = QUARTZ_CompList_GetNext( This->basefilter.pOutPins, pItem );
537 QUARTZ_CompList_Unlock( This->basefilter.pOutPins );
543 void CParserImpl_ReleaseListOfOutPins( CParserImpl* This )
545 QUARTZ_CompListItem* pItem;
547 QUARTZ_CompList_Lock( This->basefilter.pOutPins );
550 pItem = QUARTZ_CompList_GetFirst( This->basefilter.pOutPins );
553 QUARTZ_CompList_RemoveComp(
554 This->basefilter.pOutPins,
555 QUARTZ_CompList_GetItemPtr(pItem) );
557 QUARTZ_CompList_Unlock( This->basefilter.pOutPins );
562 HRESULT CParserImpl_BeginThread( CParserImpl* This )
567 if ( This->m_hEventInit != (HANDLE)NULL &&
568 This->m_hThread != (HANDLE)NULL )
571 This->m_hEventInit = CreateEventA(NULL,TRUE,FALSE,NULL);
572 if ( This->m_hEventInit == (HANDLE)NULL )
573 return E_OUTOFMEMORY;
575 /* create the processing thread. */
576 This->m_hThread = CreateThread(
578 CParserImplThread_Entry,
580 0, &This->m_dwThreadId );
581 if ( This->m_hThread == (HANDLE)NULL )
584 hEvents[0] = This->m_hEventInit;
585 hEvents[1] = This->m_hThread;
587 dwRes = WaitForMultipleObjects(2,hEvents,FALSE,INFINITE);
588 if ( dwRes != WAIT_OBJECT_0 )
595 void CParserImpl_EndThread( CParserImpl* This )
597 TRACE("(%p)\n",This);
598 if ( This->m_hThread != (HANDLE)NULL )
600 if ( PostThreadMessageA(
601 This->m_dwThreadId, QUARTZ_MSG_EXITTHREAD, 0, 0 ) )
603 WaitForSingleObject( This->m_hThread, INFINITE );
605 CloseHandle( This->m_hThread );
606 This->m_hThread = (HANDLE)NULL;
607 This->m_dwThreadId = 0;
609 if ( This->m_hEventInit != (HANDLE)NULL )
611 CloseHandle( This->m_hEventInit );
612 This->m_hEventInit = (HANDLE)NULL;
617 HRESULT CParserImpl_MemCommit( CParserImpl* This )
621 IMemAllocator* pAlloc;
623 TRACE("(%p)\n",This);
625 if ( This->m_pAllocator == NULL )
628 hr = IMemAllocator_Commit( This->m_pAllocator );
632 if ( This->m_ppOutPins != NULL && This->m_cOutStreams > 0 )
634 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
636 pAlloc = This->m_ppOutPins[nIndex]->m_pOutPinAllocator;
637 if ( pAlloc != NULL && pAlloc != This->m_pAllocator )
639 hr = IMemAllocator_Commit( pAlloc );
650 HRESULT CParserImpl_GetPreferredTimeFormat( CParserImpl* This, GUID* pguidFormat )
652 static const GUID* tryformats[] =
654 &TIME_FORMAT_MEDIA_TIME,
663 if ( This->m_pHandler->pIsTimeFormatSupported == NULL )
667 while ( tryformats[n] != NULL )
669 if ( This->m_pHandler->pIsTimeFormatSupported( This, tryformats[n] ) == S_OK )
671 memcpy( pguidFormat, tryformats[n], sizeof(GUID) );
682 /***************************************************************************
684 * CParserImpl methods
688 static HRESULT CParserImpl_OnActive( CBaseFilterImpl* pImpl )
690 CParserImpl_THIS(pImpl,basefilter);
692 TRACE( "(%p)\n", This );
694 if ( !CParserImpl_OutPinsAreConnected(This) )
700 static HRESULT CParserImpl_OnInactive( CBaseFilterImpl* pImpl )
702 CParserImpl_THIS(pImpl,basefilter);
705 TRACE( "(%p)\n", This );
707 if ( !CParserImpl_OutPinsAreConnected(This) )
710 hr = CParserImpl_MemCommit(This);
713 hr = CParserImpl_BeginThread(This);
716 CParserImpl_EndThread(This);
723 static HRESULT CParserImpl_OnStop( CBaseFilterImpl* pImpl )
725 CParserImpl_THIS(pImpl,basefilter);
727 FIXME( "(%p)\n", This );
729 CParserImpl_EndThread(This);
735 static const CBaseFilterHandlers filterhandlers =
737 CParserImpl_OnActive, /* pOnActive */
738 CParserImpl_OnInactive, /* pOnInactive */
739 CParserImpl_OnStop, /* pOnStop */
743 /***************************************************************************
745 * CParserInPinImpl methods
749 static HRESULT CParserInPinImpl_OnPreConnect( CPinBaseImpl* pImpl, IPin* pPin )
751 CParserInPinImpl_THIS(pImpl,pin);
755 IAsyncReader* pReader = NULL;
756 LPCWSTR pwszOutPinName;
757 IMemAllocator* pAllocActual;
760 TRACE("(%p,%p)\n",This,pPin);
762 if ( This->pParser->m_pHandler->pInitParser == NULL ||
763 This->pParser->m_pHandler->pUninitParser == NULL ||
764 This->pParser->m_pHandler->pGetOutPinName == NULL ||
765 This->pParser->m_pHandler->pGetStreamType == NULL ||
766 This->pParser->m_pHandler->pCheckStreamType == NULL ||
767 This->pParser->m_pHandler->pGetAllocProp == NULL ||
768 This->pParser->m_pHandler->pGetNextRequest == NULL )
770 FIXME("this parser is not implemented.\n");
774 /* at first, release all output pins. */
775 if ( CParserImpl_OutPinsAreConnected(This->pParser) )
777 CParserImpl_ReleaseListOfOutPins(This->pParser);
778 CParserImpl_ReleaseOutPins(This->pParser);
780 CParserImpl_SetAsyncReader( This->pParser, NULL );
781 hr = IPin_QueryInterface( pPin, &IID_IAsyncReader, (void**)&pReader );
784 CParserImpl_SetAsyncReader( This->pParser, pReader );
785 IAsyncReader_Release(pReader);
787 /* initialize parser. */
788 hr = This->pParser->m_pHandler->pInitParser(This->pParser,&This->pParser->m_cOutStreams);
791 This->pParser->m_ppOutPins = (CParserOutPinImpl**)QUARTZ_AllocMem(
792 sizeof(CParserOutPinImpl*) * This->pParser->m_cOutStreams );
793 if ( This->pParser->m_ppOutPins == NULL )
794 return E_OUTOFMEMORY;
795 for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
796 This->pParser->m_ppOutPins[nIndex] = NULL;
798 /* create and initialize an allocator. */
799 hr = This->pParser->m_pHandler->pGetAllocProp(This->pParser,&This->pParser->m_propAlloc);
802 if ( This->pParser->m_propAlloc.cbAlign == 0 )
803 This->pParser->m_propAlloc.cbAlign = 1;
805 if ( This->pParser->m_pAllocator == NULL )
807 hr = QUARTZ_CreateMemoryAllocator(NULL,(void**)&punk);
810 hr = IUnknown_QueryInterface( punk, &IID_IMemAllocator, (void**)&This->pParser->m_pAllocator );
811 IUnknown_Release(punk);
816 hr = IAsyncReader_RequestAllocator(pReader,This->pParser->m_pAllocator,&This->pParser->m_propAlloc,&pAllocActual);
819 IMemAllocator_Release(This->pParser->m_pAllocator);
820 This->pParser->m_pAllocator = pAllocActual;
822 /* create output pins. */
823 for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
825 pwszOutPinName = This->pParser->m_pHandler->pGetOutPinName(This->pParser,nIndex);
826 if ( pwszOutPinName == NULL )
828 hr = QUARTZ_CreateParserOutPin(
830 &This->pParser->m_csParser,
831 &This->pParser->m_ppOutPins[nIndex],
832 nIndex, pwszOutPinName );
834 hr = QUARTZ_CompList_AddTailComp(
835 This->pParser->basefilter.pOutPins,
836 (IUnknown*)&(This->pParser->m_ppOutPins[nIndex]->pin),
840 pmt = &This->pParser->m_ppOutPins[nIndex]->m_mtOut;
841 QUARTZ_MediaType_Free( pmt );
842 ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
843 hr = This->pParser->m_pHandler->pGetStreamType(This->pParser,nIndex,pmt);
846 ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
849 This->pParser->m_ppOutPins[nIndex]->pin.cAcceptTypes = 1;
850 This->pParser->m_ppOutPins[nIndex]->pin.pmtAcceptTypes = pmt;
856 static HRESULT CParserInPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
858 CParserInPinImpl_THIS(pImpl,pin);
860 CParserImpl_OnInactive(&This->pParser->basefilter);
861 CParserImpl_OnStop(&This->pParser->basefilter);
862 if ( This->pParser->m_pHandler->pUninitParser != NULL )
863 This->pParser->m_pHandler->pUninitParser(This->pParser);
864 CParserImpl_SetAsyncReader( This->pParser, NULL );
865 if ( This->pParser->m_pAllocator != NULL )
867 IMemAllocator_Decommit(This->pParser->m_pAllocator);
868 IMemAllocator_Release(This->pParser->m_pAllocator);
869 This->pParser->m_pAllocator = NULL;
875 static HRESULT CParserInPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
877 CParserInPinImpl_THIS(pImpl,pin);
879 TRACE("(%p,%p)\n",This,pmt);
881 if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Stream ) )
887 static const CBasePinHandlers inputpinhandlers =
889 CParserInPinImpl_OnPreConnect, /* pOnPreConnect */
890 NULL, /* pOnPostConnect */
891 CParserInPinImpl_OnDisconnect, /* pOnDisconnect */
892 CParserInPinImpl_CheckMediaType, /* pCheckMediaType */
893 NULL, /* pQualityNotify */
895 NULL, /* pReceiveCanBlock */
896 NULL, /* pEndOfStream */
897 NULL, /* pBeginFlush */
898 NULL, /* pEndFlush */
899 NULL, /* pNewSegment */
902 /***************************************************************************
904 * CParserOutPinImpl methods
908 static HRESULT CParserOutPinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPin )
910 CParserOutPinImpl_THIS(pImpl,pin);
911 ALLOCATOR_PROPERTIES propReq;
912 ALLOCATOR_PROPERTIES propActual;
913 IMemAllocator* pAllocator;
915 BOOL bNewAllocator = FALSE;
917 TRACE("(%p,%p)\n",This,pPin);
919 if ( This->pin.pMemInputPinConnectedTo == NULL )
922 if ( This->m_pOutPinAllocator != NULL )
924 IMemAllocator_Release(This->m_pOutPinAllocator);
925 This->m_pOutPinAllocator = NULL;
928 /* try to use This->pParser->m_pAllocator. */
929 ZeroMemory( &propReq, sizeof(ALLOCATOR_PROPERTIES) );
930 hr = IMemInputPin_GetAllocatorRequirements(
931 This->pin.pMemInputPinConnectedTo, &propReq );
932 if ( propReq.cbAlign != 0 )
934 if ( This->pParser->m_propAlloc.cbAlign != ( This->pParser->m_propAlloc.cbAlign / propReq.cbAlign * propReq.cbAlign ) )
935 bNewAllocator = TRUE;
937 if ( propReq.cbPrefix != 0 )
938 bNewAllocator = TRUE;
939 if ( !bNewAllocator )
941 hr = IMemInputPin_NotifyAllocator(
942 This->pin.pMemInputPinConnectedTo,
943 This->pParser->m_pAllocator, FALSE );
946 This->m_pOutPinAllocator = This->pParser->m_pAllocator;
947 IMemAllocator_AddRef(This->m_pOutPinAllocator);
952 hr = IMemInputPin_GetAllocator(
953 This->pin.pMemInputPinConnectedTo, &pAllocator );
956 hr = IMemAllocator_SetProperties( pAllocator, &This->pParser->m_propAlloc, &propActual );
958 hr = IMemInputPin_NotifyAllocator(
959 This->pin.pMemInputPinConnectedTo, pAllocator, FALSE );
962 IMemAllocator_Release(pAllocator);
966 This->m_pOutPinAllocator = pAllocator;
970 static HRESULT CParserOutPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
972 CParserOutPinImpl_THIS(pImpl,pin);
974 if ( This->m_pOutPinAllocator != NULL )
976 IMemAllocator_Release(This->m_pOutPinAllocator);
977 This->m_pOutPinAllocator = NULL;
983 static HRESULT CParserOutPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
985 CParserOutPinImpl_THIS(pImpl,pin);
988 TRACE("(%p,%p)\n",This,pmt);
992 if ( This->pParser->m_pHandler->pCheckStreamType == NULL )
995 hr = This->pParser->m_pHandler->pCheckStreamType( This->pParser, This->nStreamIndex, pmt );
1003 static const CBasePinHandlers outputpinhandlers =
1005 NULL, /* pOnPreConnect */
1006 CParserOutPinImpl_OnPostConnect, /* pOnPostConnect */
1007 CParserOutPinImpl_OnDisconnect, /* pOnDisconnect */
1008 CParserOutPinImpl_CheckMediaType, /* pCheckMediaType */
1009 NULL, /* pQualityNotify */
1010 OutputPinSync_Receive, /* pReceive */
1011 OutputPinSync_ReceiveCanBlock, /* pReceiveCanBlock */
1012 OutputPinSync_EndOfStream, /* pEndOfStream */
1013 OutputPinSync_BeginFlush, /* pBeginFlush */
1014 OutputPinSync_EndFlush, /* pEndFlush */
1015 OutputPinSync_NewSegment, /* pNewSegment */
1018 /***************************************************************************
1020 * new/delete CParserImpl
1024 /* can I use offsetof safely? - FIXME? */
1025 static QUARTZ_IFEntry FilterIFEntries[] =
1027 { &IID_IPersist, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1028 { &IID_IMediaFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1029 { &IID_IBaseFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
1032 static void QUARTZ_DestroyParser(IUnknown* punk)
1034 CParserImpl_THIS(punk,unk);
1036 TRACE( "(%p)\n", This );
1038 if ( This->m_pInPin != NULL )
1039 CParserInPinImpl_OnDisconnect(&This->m_pInPin->pin);
1041 CParserImpl_SetAsyncReader( This, NULL );
1042 if ( This->m_pAllocator != NULL )
1044 IMemAllocator_Release(This->m_pAllocator);
1045 This->m_pAllocator = NULL;
1047 if ( This->m_pInPin != NULL )
1049 IUnknown_Release(This->m_pInPin->unk.punkControl);
1050 This->m_pInPin = NULL;
1052 CParserImpl_ReleaseOutPins( This );
1054 DeleteCriticalSection( &This->m_csParser );
1056 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
1059 HRESULT QUARTZ_CreateParser(
1060 IUnknown* punkOuter,void** ppobj,
1061 const CLSID* pclsidParser,
1062 LPCWSTR pwszParserName,
1063 LPCWSTR pwszInPinName,
1064 const ParserHandlers* pHandler )
1066 CParserImpl* This = NULL;
1069 TRACE("(%p,%p)\n",punkOuter,ppobj);
1071 This = (CParserImpl*)
1072 QUARTZ_AllocObj( sizeof(CParserImpl) );
1074 return E_OUTOFMEMORY;
1075 ZeroMemory( This, sizeof(CParserImpl) );
1077 This->m_pInPin = NULL;
1078 This->m_cOutStreams = 0;
1079 This->m_ppOutPins = NULL;
1080 memcpy( &This->m_guidTimeFormat, &TIME_FORMAT_NONE, sizeof(GUID) );
1081 This->m_pReader = NULL;
1082 This->m_pAllocator = NULL;
1083 ZeroMemory( &This->m_propAlloc, sizeof(ALLOCATOR_PROPERTIES) );
1084 This->m_hEventInit = (HANDLE)NULL;
1085 This->m_hThread = (HANDLE)NULL;
1086 This->m_dwThreadId = 0;
1087 This->m_bSendEOS = FALSE;
1088 This->m_pHandler = pHandler;
1089 This->m_pUserData = NULL;
1091 QUARTZ_IUnkInit( &This->unk, punkOuter );
1093 hr = CBaseFilterImpl_InitIBaseFilter(
1095 This->unk.punkControl,
1099 if ( SUCCEEDED(hr) )
1101 /* construct this class. */
1106 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
1112 QUARTZ_FreeObj(This);
1116 This->unk.pEntries = FilterIFEntries;
1117 This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
1118 This->unk.pOnFinalRelease = QUARTZ_DestroyParser;
1119 InitializeCriticalSection( &This->m_csParser );
1121 /* create the input pin. */
1122 hr = QUARTZ_CreateParserInPin(
1127 if ( SUCCEEDED(hr) )
1128 hr = QUARTZ_CompList_AddComp(
1129 This->basefilter.pInPins,
1130 (IUnknown*)&(This->m_pInPin->pin),
1135 IUnknown_Release( This->unk.punkControl );
1139 *ppobj = (void*)&(This->unk);
1141 (void)CParserImpl_GetPreferredTimeFormat( This, &This->m_guidTimeFormat );
1146 /***************************************************************************
1148 * new/delete CParserInPinImpl
1152 /* can I use offsetof safely? - FIXME? */
1153 static QUARTZ_IFEntry InPinIFEntries[] =
1155 { &IID_IPin, offsetof(CParserInPinImpl,pin)-offsetof(CParserInPinImpl,unk) },
1156 { &IID_IMemInputPin, offsetof(CParserInPinImpl,meminput)-offsetof(CParserInPinImpl,unk) },
1159 static void QUARTZ_DestroyParserInPin(IUnknown* punk)
1161 CParserInPinImpl_THIS(punk,unk);
1163 TRACE( "(%p)\n", This );
1165 CPinBaseImpl_UninitIPin( &This->pin );
1166 CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
1169 HRESULT QUARTZ_CreateParserInPin(
1170 CParserImpl* pFilter,
1171 CRITICAL_SECTION* pcsPin,
1172 CParserInPinImpl** ppPin,
1173 LPCWSTR pwszPinName )
1175 CParserInPinImpl* This = NULL;
1178 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
1180 This = (CParserInPinImpl*)
1181 QUARTZ_AllocObj( sizeof(CParserInPinImpl) );
1183 return E_OUTOFMEMORY;
1185 QUARTZ_IUnkInit( &This->unk, NULL );
1186 This->pParser = pFilter;
1188 hr = CPinBaseImpl_InitIPin(
1190 This->unk.punkControl,
1192 &pFilter->basefilter,
1195 &inputpinhandlers );
1197 if ( SUCCEEDED(hr) )
1199 hr = CMemInputPinBaseImpl_InitIMemInputPin(
1201 This->unk.punkControl,
1205 CPinBaseImpl_UninitIPin( &This->pin );
1211 QUARTZ_FreeObj(This);
1215 This->unk.pEntries = InPinIFEntries;
1216 This->unk.dwEntries = sizeof(InPinIFEntries)/sizeof(InPinIFEntries[0]);
1217 This->unk.pOnFinalRelease = QUARTZ_DestroyParserInPin;
1221 TRACE("returned successfully.\n");
1227 /***************************************************************************
1229 * new/delete CParserOutPinImpl
1233 /* can I use offsetof safely? - FIXME? */
1234 static QUARTZ_IFEntry OutPinIFEntries[] =
1236 { &IID_IPin, offsetof(CParserOutPinImpl,pin)-offsetof(CParserOutPinImpl,unk) },
1237 { &IID_IQualityControl, offsetof(CParserOutPinImpl,qcontrol)-offsetof(CParserOutPinImpl,unk) },
1238 { &IID_IMediaSeeking, offsetof(CParserOutPinImpl,mediaseeking)-offsetof(CParserOutPinImpl,unk) },
1239 { &IID_IMediaPosition, offsetof(CParserOutPinImpl,mediaposition)-offsetof(CParserOutPinImpl,unk) },
1242 static void QUARTZ_DestroyParserOutPin(IUnknown* punk)
1244 CParserOutPinImpl_THIS(punk,unk);
1246 TRACE( "(%p)\n", This );
1248 QUARTZ_MediaType_Free( &This->m_mtOut );
1249 if ( This->m_pOutPinAllocator != NULL )
1250 IMemAllocator_Release(This->m_pOutPinAllocator);
1252 CParserOutPinImpl_UninitIMediaPosition(This);
1253 CParserOutPinImpl_UninitIMediaSeeking(This);
1254 CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
1255 CPinBaseImpl_UninitIPin( &This->pin );
1259 HRESULT QUARTZ_CreateParserOutPin(
1260 CParserImpl* pFilter,
1261 CRITICAL_SECTION* pcsPin,
1262 CParserOutPinImpl** ppPin,
1264 LPCWSTR pwszPinName )
1266 CParserOutPinImpl* This = NULL;
1269 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
1271 This = (CParserOutPinImpl*)
1272 QUARTZ_AllocObj( sizeof(CParserOutPinImpl) );
1274 return E_OUTOFMEMORY;
1276 QUARTZ_IUnkInit( &This->unk, NULL );
1277 This->pParser = pFilter;
1278 This->nStreamIndex = nStreamIndex;
1279 ZeroMemory( &This->m_mtOut, sizeof(AM_MEDIA_TYPE) );
1280 This->m_pOutPinAllocator = NULL;
1281 This->m_pUserData = NULL;
1282 This->m_bReqUsed = FALSE;
1283 This->m_pReqSample = NULL;
1284 This->m_llReqStart = 0;
1285 This->m_lReqLength = 0;
1286 This->m_rtReqStart = 0;
1287 This->m_rtReqStop = 0;
1288 This->m_dwSampleFlags = 0;
1291 hr = CPinBaseImpl_InitIPin(
1293 This->unk.punkControl,
1295 &pFilter->basefilter,
1298 &outputpinhandlers );
1300 if ( SUCCEEDED(hr) )
1302 hr = CQualityControlPassThruImpl_InitIQualityControl(
1304 This->unk.punkControl,
1306 if ( SUCCEEDED(hr) )
1308 hr = CParserOutPinImpl_InitIMediaSeeking(This);
1309 if ( SUCCEEDED(hr) )
1311 hr = CParserOutPinImpl_InitIMediaPosition(This);
1314 CParserOutPinImpl_UninitIMediaSeeking(This);
1319 CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
1324 CPinBaseImpl_UninitIPin( &This->pin );
1330 QUARTZ_FreeObj(This);
1334 This->unk.pEntries = OutPinIFEntries;
1335 This->unk.dwEntries = sizeof(OutPinIFEntries)/sizeof(OutPinIFEntries[0]);
1336 This->unk.pOnFinalRelease = QUARTZ_DestroyParserOutPin;
1340 TRACE("returned successfully.\n");
1346 /***************************************************************************
1348 * IMediaSeeking for CParserOutPinImpl
1352 static HRESULT WINAPI
1353 IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj)
1355 CParserOutPinImpl_THIS(iface,mediaseeking);
1357 TRACE("(%p)->()\n",This);
1359 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
1363 IMediaSeeking_fnAddRef(IMediaSeeking* iface)
1365 CParserOutPinImpl_THIS(iface,mediaseeking);
1367 TRACE("(%p)->()\n",This);
1369 return IUnknown_AddRef(This->unk.punkControl);
1373 IMediaSeeking_fnRelease(IMediaSeeking* iface)
1375 CParserOutPinImpl_THIS(iface,mediaseeking);
1377 TRACE("(%p)->()\n",This);
1379 return IUnknown_Release(This->unk.punkControl);
1383 static HRESULT WINAPI
1384 IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
1386 CParserOutPinImpl_THIS(iface,mediaseeking);
1387 HRESULT hr = E_NOTIMPL;
1389 TRACE("(%p)->(%p)\n",This,pdwCaps);
1391 if ( pdwCaps == NULL )
1394 EnterCriticalSection( &This->pParser->m_csParser );
1395 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
1397 FIXME("(%p)->(%p) not implemented\n",This,pdwCaps);
1401 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, pdwCaps );
1403 LeaveCriticalSection( &This->pParser->m_csParser );
1408 static HRESULT WINAPI
1409 IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
1411 CParserOutPinImpl_THIS(iface,mediaseeking);
1412 HRESULT hr = E_NOTIMPL;
1415 TRACE("(%p)->(%p)\n",This,pdwCaps);
1417 if ( pdwCaps == NULL )
1420 EnterCriticalSection( &This->pParser->m_csParser );
1421 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
1423 FIXME("(%p)->(%p) not implemented\n",This,pdwCaps);
1427 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
1428 if ( SUCCEEDED(hr) )
1431 if ( dwCaps == *pdwCaps )
1441 LeaveCriticalSection( &This->pParser->m_csParser );
1448 static HRESULT WINAPI
1449 IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat)
1451 CParserOutPinImpl_THIS(iface,mediaseeking);
1452 HRESULT hr = E_NOTIMPL;
1454 TRACE("(%p)->(%s)\n",This,debugstr_guid(pidFormat));
1456 if ( pidFormat == NULL )
1459 EnterCriticalSection( &This->pParser->m_csParser );
1460 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1462 FIXME("(%p)->(%s) not implemented\n",This,debugstr_guid(pidFormat));
1466 hr = This->pParser->m_pHandler->pIsTimeFormatSupported( This->pParser, pidFormat );
1468 LeaveCriticalSection( &This->pParser->m_csParser );
1473 static HRESULT WINAPI
1474 IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat)
1476 CParserOutPinImpl_THIS(iface,mediaseeking);
1479 TRACE("(%p)->(%p)\n",This,pidFormat);
1481 EnterCriticalSection( &This->pParser->m_csParser );
1482 hr = CParserImpl_GetPreferredTimeFormat( This->pParser, pidFormat );
1483 LeaveCriticalSection( &This->pParser->m_csParser );
1488 static HRESULT WINAPI
1489 IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat)
1491 CParserOutPinImpl_THIS(iface,mediaseeking);
1492 HRESULT hr = E_NOTIMPL;
1494 TRACE("(%p)->(%p)\n",This,pidFormat);
1496 if ( pidFormat == NULL )
1499 EnterCriticalSection( &This->pParser->m_csParser );
1500 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1502 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1506 memcpy( pidFormat, &This->pParser->m_guidTimeFormat, sizeof(GUID) );
1508 LeaveCriticalSection( &This->pParser->m_csParser );
1513 static HRESULT WINAPI
1514 IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
1516 CParserOutPinImpl_THIS(iface,mediaseeking);
1517 HRESULT hr = E_NOTIMPL;
1519 TRACE("(%p)->(%p)\n",This,pidFormat);
1521 if ( pidFormat == NULL )
1524 EnterCriticalSection( &This->pParser->m_csParser );
1525 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1527 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1531 hr = IsEqualGUID( pidFormat, &This->pParser->m_guidTimeFormat ) ? S_OK : S_FALSE;
1533 LeaveCriticalSection( &This->pParser->m_csParser );
1538 static HRESULT WINAPI
1539 IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
1541 CParserOutPinImpl_THIS(iface,mediaseeking);
1542 HRESULT hr = E_NOTIMPL;
1544 TRACE("(%p)->(%p)\n",This,pidFormat);
1546 if ( pidFormat == NULL )
1549 EnterCriticalSection( &This->pParser->m_csParser );
1550 if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
1552 FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
1556 if ( This->pParser->m_pHandler->pIsTimeFormatSupported( This->pParser, pidFormat ) == S_OK )
1558 memcpy( &This->pParser->m_guidTimeFormat, pidFormat, sizeof(GUID) );
1561 LeaveCriticalSection( &This->pParser->m_csParser );
1566 static HRESULT WINAPI
1567 IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
1569 CParserOutPinImpl_THIS(iface,mediaseeking);
1570 HRESULT hr = E_NOTIMPL;
1572 TRACE("(%p)->(%p)\n",This,pllDuration);
1574 if ( pllDuration == NULL )
1577 EnterCriticalSection( &This->pParser->m_csParser );
1578 if ( This->pParser->m_pHandler->pGetDuration == NULL )
1580 FIXME("(%p)->(%p) not implemented\n",This,pllDuration);
1584 hr = This->pParser->m_pHandler->pGetDuration( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllDuration );
1586 LeaveCriticalSection( &This->pParser->m_csParser );
1591 static HRESULT WINAPI
1592 IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos)
1594 CParserOutPinImpl_THIS(iface,mediaseeking);
1595 HRESULT hr = E_NOTIMPL;
1597 TRACE("(%p)->(%p)\n",This,pllPos);
1599 if ( pllPos == NULL )
1602 EnterCriticalSection( &This->pParser->m_csParser );
1603 if ( This->pParser->m_pHandler->pGetStopPos == NULL )
1605 FIXME("(%p)->(%p) not implemented\n",This,pllPos);
1609 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllPos );
1611 LeaveCriticalSection( &This->pParser->m_csParser );
1616 static HRESULT WINAPI
1617 IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos)
1619 CParserOutPinImpl_THIS(iface,mediaseeking);
1620 HRESULT hr = E_NOTIMPL;
1622 TRACE("(%p)->(%p)\n",This,pllPos);
1624 if ( pllPos == NULL )
1627 EnterCriticalSection( &This->pParser->m_csParser );
1628 if ( This->pParser->m_pHandler->pGetCurPos == NULL )
1630 FIXME("(%p)->(%p) not implemented\n",This,pllPos);
1634 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllPos );
1636 LeaveCriticalSection( &This->pParser->m_csParser );
1641 static HRESULT WINAPI
1642 IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn)
1644 CParserOutPinImpl_THIS(iface,mediaseeking);
1646 FIXME("(%p)->() stub!\n",This);
1651 static HRESULT WINAPI
1652 IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags)
1654 CParserOutPinImpl_THIS(iface,mediaseeking);
1656 FIXME("(%p)->() stub!\n",This);
1661 static HRESULT WINAPI
1662 IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop)
1664 CParserOutPinImpl_THIS(iface,mediaseeking);
1665 HRESULT hr = E_NOTIMPL;
1667 TRACE("(%p)->(%p,%p)\n",This,pllCur,pllStop);
1669 if ( pllCur == NULL || pllStop == NULL )
1672 EnterCriticalSection( &This->pParser->m_csParser );
1673 if ( This->pParser->m_pHandler->pGetCurPos == NULL ||
1674 This->pParser->m_pHandler->pGetStopPos == NULL )
1676 FIXME("(%p)->(%p,%p) not implemented\n",This,pllCur,pllStop);
1680 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllCur );
1681 if ( SUCCEEDED(hr) )
1682 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllStop );
1684 LeaveCriticalSection( &This->pParser->m_csParser );
1689 static HRESULT WINAPI
1690 IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast)
1692 CParserOutPinImpl_THIS(iface,mediaseeking);
1694 FIXME("(%p)->() stub!\n",This);
1699 static HRESULT WINAPI
1700 IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate)
1702 CParserOutPinImpl_THIS(iface,mediaseeking);
1704 FIXME("(%p)->() stub!\n",This);
1709 static HRESULT WINAPI
1710 IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate)
1712 CParserOutPinImpl_THIS(iface,mediaseeking);
1714 FIXME("(%p)->() stub!\n",This);
1719 static HRESULT WINAPI
1720 IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll)
1722 CParserOutPinImpl_THIS(iface,mediaseeking);
1724 FIXME("(%p)->() stub!\n",This);
1732 static ICOM_VTABLE(IMediaSeeking) imediaseeking =
1734 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1735 /* IUnknown fields */
1736 IMediaSeeking_fnQueryInterface,
1737 IMediaSeeking_fnAddRef,
1738 IMediaSeeking_fnRelease,
1739 /* IMediaSeeking fields */
1740 IMediaSeeking_fnGetCapabilities,
1741 IMediaSeeking_fnCheckCapabilities,
1742 IMediaSeeking_fnIsFormatSupported,
1743 IMediaSeeking_fnQueryPreferredFormat,
1744 IMediaSeeking_fnGetTimeFormat,
1745 IMediaSeeking_fnIsUsingTimeFormat,
1746 IMediaSeeking_fnSetTimeFormat,
1747 IMediaSeeking_fnGetDuration,
1748 IMediaSeeking_fnGetStopPosition,
1749 IMediaSeeking_fnGetCurrentPosition,
1750 IMediaSeeking_fnConvertTimeFormat,
1751 IMediaSeeking_fnSetPositions,
1752 IMediaSeeking_fnGetPositions,
1753 IMediaSeeking_fnGetAvailable,
1754 IMediaSeeking_fnSetRate,
1755 IMediaSeeking_fnGetRate,
1756 IMediaSeeking_fnGetPreroll,
1759 HRESULT CParserOutPinImpl_InitIMediaSeeking( CParserOutPinImpl* This )
1761 TRACE("(%p)\n",This);
1762 ICOM_VTBL(&This->mediaseeking) = &imediaseeking;
1767 void CParserOutPinImpl_UninitIMediaSeeking( CParserOutPinImpl* This )
1769 TRACE("(%p)\n",This);
1772 /***************************************************************************
1774 * IMediaPosition for CParserOutPinImpl
1778 static HRESULT WINAPI
1779 IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj)
1781 CParserOutPinImpl_THIS(iface,mediaposition);
1783 TRACE("(%p)->()\n",This);
1785 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
1789 IMediaPosition_fnAddRef(IMediaPosition* iface)
1791 CParserOutPinImpl_THIS(iface,mediaposition);
1793 TRACE("(%p)->()\n",This);
1795 return IUnknown_AddRef(This->unk.punkControl);
1799 IMediaPosition_fnRelease(IMediaPosition* iface)
1801 CParserOutPinImpl_THIS(iface,mediaposition);
1803 TRACE("(%p)->()\n",This);
1805 return IUnknown_Release(This->unk.punkControl);
1808 static HRESULT WINAPI
1809 IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo)
1811 CParserOutPinImpl_THIS(iface,mediaposition);
1813 FIXME("(%p)->() stub!\n",This);
1818 static HRESULT WINAPI
1819 IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
1821 CParserOutPinImpl_THIS(iface,mediaposition);
1823 FIXME("(%p)->() stub!\n",This);
1828 static HRESULT WINAPI
1829 IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
1831 CParserOutPinImpl_THIS(iface,mediaposition);
1833 FIXME("(%p)->() stub!\n",This);
1838 static HRESULT WINAPI
1839 IMediaPosition_fnInvoke(IMediaPosition* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1841 CParserOutPinImpl_THIS(iface,mediaposition);
1843 FIXME("(%p)->() stub!\n",This);
1849 static HRESULT WINAPI
1850 IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
1852 CParserOutPinImpl_THIS(iface,mediaposition);
1853 HRESULT hr = E_NOTIMPL;
1856 TRACE("(%p)->(%p)\n",This,prefTime);
1858 if ( prefTime == NULL )
1861 EnterCriticalSection( &This->pParser->m_csParser );
1862 if ( This->pParser->m_pHandler->pGetDuration == NULL )
1864 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1868 hr = This->pParser->m_pHandler->pGetDuration( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1869 if ( SUCCEEDED(hr) )
1870 *prefTime = (REFTIME)llPos;
1872 LeaveCriticalSection( &This->pParser->m_csParser );
1877 static HRESULT WINAPI
1878 IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
1880 CParserOutPinImpl_THIS(iface,mediaposition);
1881 HRESULT hr = E_NOTIMPL;
1884 FIXME("(%p)->() stub!\n",This);
1887 EnterCriticalSection( &This->pParser->m_csParser );
1888 if ( This->pParser->m_pHandler->pSetCurPos == NULL )
1890 FIXME("(%p)->() not implemented\n",This);
1894 llPos = (LONGLONG)refTime;
1895 hr = This->pParser->m_pHandler->pSetCurPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, llPos );
1896 /* FIXME - flush all streams. */
1898 LeaveCriticalSection( &This->pParser->m_csParser );
1904 static HRESULT WINAPI
1905 IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
1907 CParserOutPinImpl_THIS(iface,mediaposition);
1908 HRESULT hr = E_NOTIMPL;
1911 TRACE("(%p)->(%p)\n",This,prefTime);
1913 if ( prefTime == NULL )
1916 EnterCriticalSection( &This->pParser->m_csParser );
1917 if ( This->pParser->m_pHandler->pGetCurPos == NULL )
1919 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1923 hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1924 if ( SUCCEEDED(hr) )
1925 *prefTime = (REFTIME)llPos;
1927 LeaveCriticalSection( &This->pParser->m_csParser );
1932 static HRESULT WINAPI
1933 IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
1935 CParserOutPinImpl_THIS(iface,mediaposition);
1936 HRESULT hr = E_NOTIMPL;
1939 TRACE("(%p)->(%p)\n",This,prefTime);
1941 if ( prefTime == NULL )
1944 EnterCriticalSection( &This->pParser->m_csParser );
1945 if ( This->pParser->m_pHandler->pGetStopPos == NULL )
1947 FIXME("(%p)->(%p) not implemented\n",This,prefTime);
1951 hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
1952 if ( SUCCEEDED(hr) )
1953 *prefTime = (REFTIME)llPos;
1955 LeaveCriticalSection( &This->pParser->m_csParser );
1960 static HRESULT WINAPI
1961 IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
1963 CParserOutPinImpl_THIS(iface,mediaposition);
1964 HRESULT hr = E_NOTIMPL;
1967 TRACE("(%p)->()\n",This);
1969 EnterCriticalSection( &This->pParser->m_csParser );
1970 if ( This->pParser->m_pHandler->pSetStopPos == NULL )
1972 FIXME("(%p)->() not implemented\n",This);
1976 llPos = (LONGLONG)refTime;
1977 hr = This->pParser->m_pHandler->pSetStopPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, llPos );
1979 LeaveCriticalSection( &This->pParser->m_csParser );
1984 static HRESULT WINAPI
1985 IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
1987 CParserOutPinImpl_THIS(iface,mediaposition);
1989 FIXME("(%p)->() stub!\n",This);
1994 static HRESULT WINAPI
1995 IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
1997 CParserOutPinImpl_THIS(iface,mediaposition);
1999 FIXME("(%p)->() stub!\n",This);
2004 static HRESULT WINAPI
2005 IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
2007 CParserOutPinImpl_THIS(iface,mediaposition);
2009 return IMediaSeeking_SetRate(CParserOutPinImpl_IMediaSeeking(This),dblRate);
2012 static HRESULT WINAPI
2013 IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
2015 CParserOutPinImpl_THIS(iface,mediaposition);
2017 return IMediaSeeking_GetRate(CParserOutPinImpl_IMediaSeeking(This),pdblRate);
2020 static HRESULT WINAPI
2021 IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
2023 CParserOutPinImpl_THIS(iface,mediaposition);
2024 HRESULT hr = E_NOTIMPL;
2027 TRACE("(%p)->(%p)\n",This,pCanSeek);
2029 if ( pCanSeek == NULL )
2032 EnterCriticalSection( &This->pParser->m_csParser );
2033 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
2035 FIXME("(%p)->(%p) not implemented\n",This,pCanSeek);
2039 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
2040 if ( SUCCEEDED(hr) )
2042 *pCanSeek = (dwCaps & AM_SEEKING_CanSeekForwards) ? OATRUE : OAFALSE;
2046 LeaveCriticalSection( &This->pParser->m_csParser );
2051 static HRESULT WINAPI
2052 IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
2054 CParserOutPinImpl_THIS(iface,mediaposition);
2055 HRESULT hr = E_NOTIMPL;
2058 TRACE("(%p)->(%p)\n",This,pCanSeek);
2060 if ( pCanSeek == NULL )
2063 EnterCriticalSection( &This->pParser->m_csParser );
2064 if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
2066 FIXME("(%p)->(%p) not implemented\n",This,pCanSeek);
2070 hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
2071 if ( SUCCEEDED(hr) )
2073 *pCanSeek = (dwCaps & AM_SEEKING_CanSeekBackwards) ? OATRUE : OAFALSE;
2077 LeaveCriticalSection( &This->pParser->m_csParser );
2083 static ICOM_VTABLE(IMediaPosition) imediaposition =
2085 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2086 /* IUnknown fields */
2087 IMediaPosition_fnQueryInterface,
2088 IMediaPosition_fnAddRef,
2089 IMediaPosition_fnRelease,
2090 /* IDispatch fields */
2091 IMediaPosition_fnGetTypeInfoCount,
2092 IMediaPosition_fnGetTypeInfo,
2093 IMediaPosition_fnGetIDsOfNames,
2094 IMediaPosition_fnInvoke,
2095 /* IMediaPosition fields */
2096 IMediaPosition_fnget_Duration,
2097 IMediaPosition_fnput_CurrentPosition,
2098 IMediaPosition_fnget_CurrentPosition,
2099 IMediaPosition_fnget_StopTime,
2100 IMediaPosition_fnput_StopTime,
2101 IMediaPosition_fnget_PrerollTime,
2102 IMediaPosition_fnput_PrerollTime,
2103 IMediaPosition_fnput_Rate,
2104 IMediaPosition_fnget_Rate,
2105 IMediaPosition_fnCanSeekForward,
2106 IMediaPosition_fnCanSeekBackward,
2110 HRESULT CParserOutPinImpl_InitIMediaPosition( CParserOutPinImpl* This )
2112 TRACE("(%p)\n",This);
2113 ICOM_VTBL(&This->mediaposition) = &imediaposition;
2118 void CParserOutPinImpl_UninitIMediaPosition( CParserOutPinImpl* This )
2120 TRACE("(%p)\n",This);