For a radio button even if the initial style includes WS_TABSTOP the
[wine/wine64.git] / dlls / quartz / parser.c
blob16ce54f8a39a13fbafae0f47b96bc2f584de88df
1 /*
2 * Implements IBaseFilter for parsers. (internal)
4 * hidenori@a2.ctktv.ne.jp
6 * FIXME - handle errors/flushing correctly.
7 * FIXME - handle seeking.
8 */
10 #include "config.h"
12 #include "windef.h"
13 #include "winbase.h"
14 #include "wingdi.h"
15 #include "winuser.h"
16 #include "mmsystem.h"
17 #include "winerror.h"
18 #include "strmif.h"
19 #include "control.h"
20 #include "vfwmsgs.h"
21 #include "evcode.h"
22 #include "uuids.h"
24 #include "debugtools.h"
25 DEFAULT_DEBUG_CHANNEL(quartz);
27 #include "quartz_private.h"
28 #include "parser.h"
29 #include "mtype.h"
30 #include "memalloc.h"
32 #define QUARTZ_MSG_EXITTHREAD (WM_APP+2)
33 #define QUARTZ_MSG_SEEK (WM_APP+3)
35 HRESULT CParserOutPinImpl_InitIMediaSeeking( CParserOutPinImpl* This );
36 void CParserOutPinImpl_UninitIMediaSeeking( CParserOutPinImpl* This );
37 HRESULT CParserOutPinImpl_InitIMediaPosition( CParserOutPinImpl* This );
38 void CParserOutPinImpl_UninitIMediaPosition( CParserOutPinImpl* This );
40 /***************************************************************************
42 * CParserImpl internal thread
46 static
47 void CParserImplThread_ClearAllRequests( CParserImpl* This )
49 ULONG nIndex;
51 TRACE("(%p)\n",This);
53 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
55 This->m_ppOutPins[nIndex]->m_bReqUsed = FALSE;
56 This->m_ppOutPins[nIndex]->m_pReqSample = NULL;
60 static
61 void CParserImplThread_ReleaseAllRequests( CParserImpl* This )
63 ULONG nIndex;
65 TRACE("(%p)\n",This);
67 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
69 if ( This->m_ppOutPins[nIndex]->m_bReqUsed )
71 if ( This->m_ppOutPins[nIndex]->m_pReqSample != NULL )
73 IMediaSample_Release(This->m_ppOutPins[nIndex]->m_pReqSample);
74 This->m_ppOutPins[nIndex]->m_pReqSample = NULL;
76 This->m_ppOutPins[nIndex]->m_bReqUsed = FALSE;
81 static
82 BOOL CParserImplThread_HasPendingSamples( CParserImpl* This )
84 ULONG nIndex;
86 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
88 if ( This->m_ppOutPins[nIndex]->m_bReqUsed &&
89 This->m_ppOutPins[nIndex]->m_pReqSample != NULL )
90 return TRUE;
93 return FALSE;
96 static
97 HRESULT CParserImplThread_FlushAllPendingSamples( CParserImpl* This )
99 HRESULT hr;
100 IMediaSample* pSample;
101 DWORD_PTR dwContext;
103 TRACE("(%p)\n",This);
105 /* remove all samples from queue. */
106 hr = IAsyncReader_BeginFlush(This->m_pReader);
107 if ( FAILED(hr) )
108 return hr;
109 IAsyncReader_EndFlush(This->m_pReader);
111 /* remove all processed samples from queue. */
112 while ( 1 )
114 hr = IAsyncReader_WaitForNext(This->m_pReader,0,&pSample,&dwContext);
115 if ( hr != S_OK )
116 break;
119 CParserImplThread_ReleaseAllRequests(This);
121 return NOERROR;
124 static HRESULT CParserImplThread_SendEndOfStream( CParserImpl* This )
126 ULONG nIndex;
127 HRESULT hr;
128 HRESULT hrRet;
129 CParserOutPinImpl* pOutPin;
131 TRACE("(%p)\n",This);
132 if ( This->m_bSendEOS )
133 return NOERROR;
134 This->m_bSendEOS = TRUE;
136 hrRet = S_OK;
137 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
139 pOutPin = This->m_ppOutPins[nIndex];
140 hr = CPinBaseImpl_SendEndOfStream(&pOutPin->pin);
141 if ( FAILED(hr) )
143 if ( SUCCEEDED(hrRet) )
144 hrRet = hr;
146 else
148 if ( hr != S_OK && hrRet == S_OK )
149 hrRet = hr;
153 return hrRet;
156 static HRESULT CParserImplThread_SendFlush( CParserImpl* This )
158 ULONG nIndex;
159 HRESULT hr;
160 HRESULT hrRet;
161 CParserOutPinImpl* pOutPin;
163 TRACE("(%p)\n",This);
164 hrRet = S_OK;
165 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
167 pOutPin = This->m_ppOutPins[nIndex];
168 hr = CPinBaseImpl_SendBeginFlush(&pOutPin->pin);
169 if ( FAILED(hr) )
171 if ( SUCCEEDED(hrRet) )
172 hrRet = hr;
174 else
176 if ( hr != S_OK && hrRet == S_OK )
177 hrRet = hr;
178 hr = CPinBaseImpl_SendEndFlush(&pOutPin->pin);
179 if ( FAILED(hr) )
180 hrRet = hr;
184 return hrRet;
187 static void CParserImplThread_ErrorAbort( CParserImpl* This, HRESULT hr )
189 CBaseFilterImpl_MediaEventNotify(
190 &This->basefilter,EC_ERRORABORT,(LONG_PTR)hr,(LONG_PTR)0);
191 CParserImplThread_SendEndOfStream(This);
194 static
195 HRESULT CParserImplThread_ProcessNextSample( CParserImpl* This )
197 IMediaSample* pSample;
198 DWORD_PTR dwContext;
199 ULONG nIndex;
200 HRESULT hr;
201 CParserOutPinImpl* pOutPin;
202 MSG msg;
204 while ( 1 )
206 if ( PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_REMOVE ) )
208 hr = NOERROR;
209 switch ( msg.message )
211 case QUARTZ_MSG_EXITTHREAD:
212 TRACE("(%p) EndThread\n",This);
213 CParserImplThread_FlushAllPendingSamples(This);
214 CParserImplThread_ClearAllRequests(This);
215 CParserImplThread_SendFlush(This);
216 CParserImplThread_SendEndOfStream(This);
217 TRACE("(%p) exit thread\n",This);
218 return S_FALSE;
219 case QUARTZ_MSG_SEEK:
220 FIXME("(%p) Seek\n",This);
221 CParserImplThread_FlushAllPendingSamples(This);
222 hr = CParserImplThread_SendFlush(This);
223 CParserImplThread_SendEndOfStream(This);
224 /* FIXME - process seeking. */
225 /* FIXME - Send NewSegment. */
226 break;
227 default:
228 FIXME( "invalid message %04u\n", (unsigned)msg.message );
229 hr = E_FAIL;
230 CParserImplThread_ErrorAbort(This,hr);
233 return hr;
236 hr = IAsyncReader_WaitForNext(This->m_pReader,PARSER_POLL_INTERVAL,&pSample,&dwContext);
237 nIndex = (ULONG)dwContext;
238 if ( hr != VFW_E_TIMEOUT )
239 break;
241 if ( FAILED(hr) )
243 CParserImplThread_ErrorAbort(This,hr);
244 return hr;
247 pOutPin = This->m_ppOutPins[nIndex];
248 if ( pOutPin != NULL && pOutPin->m_bReqUsed )
250 if ( This->m_pHandler->pProcessSample != NULL )
251 hr = This->m_pHandler->pProcessSample(This,nIndex,pOutPin->m_llReqStart,pOutPin->m_lReqLength,pOutPin->m_pReqSample);
253 if ( SUCCEEDED(hr) )
255 if ( pOutPin->m_pOutPinAllocator != NULL &&
256 pOutPin->m_pOutPinAllocator != This->m_pAllocator )
258 /* if pin has its own allocator, sample must be copied */
259 hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 );
260 if ( SUCCEEDED(hr) )
262 hr = QUARTZ_IMediaSample_Copy(
263 pSample, pOutPin->m_pReqSample, TRUE );
264 if ( SUCCEEDED(hr) )
265 hr = CPinBaseImpl_SendSample(&pOutPin->pin,pSample);
266 IMediaSample_Release(pSample);
269 else
271 hr = CPinBaseImpl_SendSample(&pOutPin->pin,pOutPin->m_pReqSample);
275 if ( FAILED(hr) )
276 CParserImplThread_ErrorAbort(This,hr);
278 IMediaSample_Release(pOutPin->m_pReqSample);
279 pOutPin->m_pReqSample = NULL;
280 pOutPin->m_bReqUsed = FALSE;
283 if ( SUCCEEDED(hr) )
284 hr = NOERROR;
286 TRACE("return %08lx\n",hr);
288 return hr;
291 static
292 DWORD WINAPI CParserImplThread_Entry( LPVOID pv )
294 CParserImpl* This = (CParserImpl*)pv;
295 BOOL bReqNext;
296 ULONG nIndex = 0;
297 HRESULT hr;
298 REFERENCE_TIME rtSampleTimeStart, rtSampleTimeEnd;
299 LONGLONG llReqStart;
300 LONG lReqLength;
301 REFERENCE_TIME rtReqStart, rtReqStop;
302 IMediaSample* pSample;
303 MSG msg;
305 /* initialize the message queue. */
306 PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE );
308 CParserImplThread_ClearAllRequests(This);
310 /* resume the owner thread. */
311 SetEvent( This->m_hEventInit );
313 TRACE( "Enter message loop.\n" );
315 bReqNext = TRUE;
316 while ( 1 )
318 if ( bReqNext )
320 /* Get the next request. */
321 hr = This->m_pHandler->pGetNextRequest( This, &nIndex, &llReqStart, &lReqLength, &rtReqStart, &rtReqStop );
322 if ( FAILED(hr) )
324 CParserImplThread_ErrorAbort(This,hr);
325 break;
327 if ( hr != S_OK )
329 /* Flush pending samples. */
330 hr = S_OK;
331 while ( CParserImplThread_HasPendingSamples(This) )
333 hr = CParserImplThread_ProcessNextSample(This);
334 if ( hr != S_OK )
335 break;
337 if ( hr != S_OK )
339 /* notification is already sent */
340 break;
343 /* Send End Of Stream. */
344 hr = CParserImplThread_SendEndOfStream(This);
345 if ( hr != S_OK )
347 /* notification is already sent */
348 break;
351 /* Blocking... */
352 hr = CParserImplThread_ProcessNextSample(This);
353 if ( hr != S_OK )
355 /* notification is already sent */
356 break;
358 continue;
360 if ( This->m_ppOutPins[nIndex]->pin.pPinConnectedTo == NULL )
361 continue;
363 rtSampleTimeStart = This->basefilter.rtStart + llReqStart * QUARTZ_TIMEUNITS;
364 rtSampleTimeEnd = (llReqStart + lReqLength) * QUARTZ_TIMEUNITS;
365 bReqNext = FALSE;
368 if ( !This->m_ppOutPins[nIndex]->m_bReqUsed )
370 hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 );
371 if ( FAILED(hr) )
373 CParserImplThread_ErrorAbort(This,hr);
374 break;
376 hr = IMediaSample_SetTime(pSample,&rtSampleTimeStart,&rtSampleTimeEnd);
377 if ( SUCCEEDED(hr) )
378 hr = IAsyncReader_Request(This->m_pReader,pSample,nIndex);
379 if ( FAILED(hr) )
381 CParserImplThread_ErrorAbort(This,hr);
382 break;
385 This->m_ppOutPins[nIndex]->m_bReqUsed = TRUE;
386 This->m_ppOutPins[nIndex]->m_pReqSample = pSample;
387 This->m_ppOutPins[nIndex]->m_llReqStart = llReqStart;
388 This->m_ppOutPins[nIndex]->m_lReqLength = lReqLength;
389 This->m_ppOutPins[nIndex]->m_rtReqStart = rtSampleTimeStart;
390 This->m_ppOutPins[nIndex]->m_rtReqStop = rtSampleTimeEnd;
391 bReqNext = TRUE;
392 continue;
395 hr = CParserImplThread_ProcessNextSample(This);
396 if ( hr != S_OK )
398 /* notification is already sent */
399 break;
403 return 0;
406 /***************************************************************************
408 * CParserImpl internal methods
412 static
413 void CParserImpl_SetAsyncReader( CParserImpl* This, IAsyncReader* pReader )
415 if ( This->m_pReader != NULL )
417 IAsyncReader_Release( This->m_pReader );
418 This->m_pReader = NULL;
420 if ( pReader != NULL )
422 This->m_pReader = pReader;
423 IAsyncReader_AddRef(This->m_pReader);
427 static
428 void CParserImpl_ReleaseOutPins( CParserImpl* This )
430 ULONG nIndex;
432 if ( This->m_ppOutPins != NULL )
434 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
436 if ( This->m_ppOutPins[nIndex] != NULL )
438 IUnknown_Release(This->m_ppOutPins[nIndex]->unk.punkControl);
439 This->m_ppOutPins[nIndex] = NULL;
442 QUARTZ_FreeMem(This->m_ppOutPins);
443 This->m_ppOutPins = NULL;
445 This->m_cOutStreams = 0;
448 static
449 BOOL CParserImpl_OutPinsAreConnected( CParserImpl* This )
451 QUARTZ_CompListItem* pItem;
452 IPin* pPin;
453 IPin* pPinPeer;
454 HRESULT hr;
456 QUARTZ_CompList_Lock( This->basefilter.pOutPins );
457 pItem = QUARTZ_CompList_GetFirst( This->basefilter.pOutPins );
458 while ( pItem != NULL )
460 if ( pItem == NULL )
461 break;
462 pPin = (IPin*)QUARTZ_CompList_GetItemPtr(pItem);
463 pPinPeer = NULL;
464 hr = IPin_ConnectedTo(pPin,&pPinPeer);
465 if ( hr == S_OK && pPinPeer != NULL )
467 IPin_Release(pPinPeer);
468 return TRUE;
470 pItem = QUARTZ_CompList_GetNext( This->basefilter.pOutPins, pItem );
472 QUARTZ_CompList_Unlock( This->basefilter.pOutPins );
474 return FALSE;
477 static
478 void CParserImpl_ReleaseListOfOutPins( CParserImpl* This )
480 QUARTZ_CompListItem* pItem;
482 QUARTZ_CompList_Lock( This->basefilter.pOutPins );
483 while ( 1 )
485 pItem = QUARTZ_CompList_GetFirst( This->basefilter.pOutPins );
486 if ( pItem == NULL )
487 break;
488 QUARTZ_CompList_RemoveComp(
489 This->basefilter.pOutPins,
490 QUARTZ_CompList_GetItemPtr(pItem) );
492 QUARTZ_CompList_Unlock( This->basefilter.pOutPins );
496 static
497 HRESULT CParserImpl_BeginThread( CParserImpl* This )
499 DWORD dwRes;
500 HANDLE hEvents[2];
502 if ( This->m_hEventInit != (HANDLE)NULL &&
503 This->m_hThread != (HANDLE)NULL )
504 return NOERROR;
506 This->m_hEventInit = CreateEventA(NULL,TRUE,FALSE,NULL);
507 if ( This->m_hEventInit == (HANDLE)NULL )
508 return E_OUTOFMEMORY;
510 /* create the processing thread. */
511 This->m_hThread = CreateThread(
512 NULL, 0,
513 CParserImplThread_Entry,
514 (LPVOID)This,
515 0, &This->m_dwThreadId );
516 if ( This->m_hThread == (HANDLE)NULL )
517 return E_FAIL;
519 hEvents[0] = This->m_hEventInit;
520 hEvents[1] = This->m_hThread;
522 dwRes = WaitForMultipleObjects(2,hEvents,FALSE,INFINITE);
523 if ( dwRes != WAIT_OBJECT_0 )
524 return E_FAIL;
526 return NOERROR;
529 static
530 void CParserImpl_EndThread( CParserImpl* This )
532 TRACE("(%p)\n",This);
533 if ( This->m_hThread != (HANDLE)NULL )
535 if ( PostThreadMessageA(
536 This->m_dwThreadId, QUARTZ_MSG_EXITTHREAD, 0, 0 ) )
538 WaitForSingleObject( This->m_hThread, INFINITE );
540 CloseHandle( This->m_hThread );
541 This->m_hThread = (HANDLE)NULL;
542 This->m_dwThreadId = 0;
544 if ( This->m_hEventInit != (HANDLE)NULL )
546 CloseHandle( This->m_hEventInit );
547 This->m_hEventInit = (HANDLE)NULL;
551 static
552 HRESULT CParserImpl_MemCommit( CParserImpl* This )
554 HRESULT hr;
555 ULONG nIndex;
556 IMemAllocator* pAlloc;
558 TRACE("(%p)\n",This);
560 if ( This->m_pAllocator == NULL )
561 return E_UNEXPECTED;
563 hr = IMemAllocator_Commit( This->m_pAllocator );
564 if ( FAILED(hr) )
565 return hr;
567 if ( This->m_ppOutPins != NULL && This->m_cOutStreams > 0 )
569 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
571 pAlloc = This->m_ppOutPins[nIndex]->m_pOutPinAllocator;
572 if ( pAlloc != NULL && pAlloc != This->m_pAllocator )
574 hr = IMemAllocator_Commit( pAlloc );
575 if ( FAILED(hr) )
576 return hr;
581 return NOERROR;
584 static
585 void CParserImpl_MemDecommit( CParserImpl* This )
587 ULONG nIndex;
588 IMemAllocator* pAlloc;
590 TRACE("(%p)\n",This);
592 if ( This->m_pAllocator != NULL )
593 IMemAllocator_Decommit( This->m_pAllocator );
595 if ( This->m_ppOutPins != NULL && This->m_cOutStreams > 0 )
597 for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
599 pAlloc = This->m_ppOutPins[nIndex]->m_pOutPinAllocator;
600 if ( pAlloc != NULL )
601 IMemAllocator_Decommit( pAlloc );
608 /***************************************************************************
610 * CParserImpl methods
614 static HRESULT CParserImpl_OnActive( CBaseFilterImpl* pImpl )
616 CParserImpl_THIS(pImpl,basefilter);
618 TRACE( "(%p)\n", This );
620 if ( !CParserImpl_OutPinsAreConnected(This) )
621 return NOERROR;
623 return NOERROR;
626 static HRESULT CParserImpl_OnInactive( CBaseFilterImpl* pImpl )
628 CParserImpl_THIS(pImpl,basefilter);
629 HRESULT hr;
631 TRACE( "(%p)\n", This );
633 if ( !CParserImpl_OutPinsAreConnected(This) )
634 return NOERROR;
636 hr = CParserImpl_MemCommit(This);
637 if ( FAILED(hr) )
638 return hr;
639 hr = CParserImpl_BeginThread(This);
640 if ( FAILED(hr) )
642 CParserImpl_EndThread(This);
643 return hr;
646 return NOERROR;
649 static HRESULT CParserImpl_OnStop( CBaseFilterImpl* pImpl )
651 CParserImpl_THIS(pImpl,basefilter);
653 FIXME( "(%p)\n", This );
655 CParserImpl_EndThread(This);
656 CParserImpl_MemDecommit(This);
657 This->m_bSendEOS = FALSE;
659 /* FIXME - reset streams. */
661 return NOERROR;
665 static const CBaseFilterHandlers filterhandlers =
667 CParserImpl_OnActive, /* pOnActive */
668 CParserImpl_OnInactive, /* pOnInactive */
669 CParserImpl_OnStop, /* pOnStop */
673 /***************************************************************************
675 * CParserInPinImpl methods
679 static HRESULT CParserInPinImpl_OnPreConnect( CPinBaseImpl* pImpl, IPin* pPin )
681 CParserInPinImpl_THIS(pImpl,pin);
682 HRESULT hr;
683 ULONG nIndex;
684 IUnknown* punk;
685 IAsyncReader* pReader = NULL;
686 LPCWSTR pwszOutPinName;
687 IMemAllocator* pAllocActual;
688 AM_MEDIA_TYPE* pmt;
690 TRACE("(%p,%p)\n",This,pPin);
692 if ( This->pParser->m_pHandler->pInitParser == NULL ||
693 This->pParser->m_pHandler->pUninitParser == NULL ||
694 This->pParser->m_pHandler->pGetOutPinName == NULL ||
695 This->pParser->m_pHandler->pGetStreamType == NULL ||
696 This->pParser->m_pHandler->pCheckStreamType == NULL ||
697 This->pParser->m_pHandler->pGetAllocProp == NULL ||
698 This->pParser->m_pHandler->pGetNextRequest == NULL )
700 FIXME("this parser is not implemented.\n");
701 return E_NOTIMPL;
704 /* at first, release all output pins. */
705 if ( CParserImpl_OutPinsAreConnected(This->pParser) )
706 return E_FAIL;
707 CParserImpl_ReleaseListOfOutPins(This->pParser);
708 CParserImpl_ReleaseOutPins(This->pParser);
710 CParserImpl_SetAsyncReader( This->pParser, NULL );
711 hr = IPin_QueryInterface( pPin, &IID_IAsyncReader, (void**)&pReader );
712 if ( FAILED(hr) )
713 return hr;
714 CParserImpl_SetAsyncReader( This->pParser, pReader );
715 IAsyncReader_Release(pReader);
717 /* initialize parser. */
718 hr = This->pParser->m_pHandler->pInitParser(This->pParser,&This->pParser->m_cOutStreams);
719 if ( FAILED(hr) )
720 return hr;
721 This->pParser->m_ppOutPins = (CParserOutPinImpl**)QUARTZ_AllocMem(
722 sizeof(CParserOutPinImpl*) * This->pParser->m_cOutStreams );
723 if ( This->pParser->m_ppOutPins == NULL )
724 return E_OUTOFMEMORY;
725 for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
726 This->pParser->m_ppOutPins[nIndex] = NULL;
728 /* create and initialize an allocator. */
729 hr = This->pParser->m_pHandler->pGetAllocProp(This->pParser,&This->pParser->m_propAlloc);
730 if ( FAILED(hr) )
731 return hr;
732 if ( This->pParser->m_propAlloc.cbAlign == 0 )
733 This->pParser->m_propAlloc.cbAlign = 1;
735 if ( This->pParser->m_pAllocator == NULL )
737 hr = QUARTZ_CreateMemoryAllocator(NULL,(void**)&punk);
738 if ( FAILED(hr) )
739 return hr;
740 hr = IUnknown_QueryInterface( punk, &IID_IMemAllocator, (void**)&This->pParser->m_pAllocator );
741 IUnknown_Release(punk);
742 if ( FAILED(hr) )
743 return hr;
745 pAllocActual = NULL;
746 hr = IAsyncReader_RequestAllocator(pReader,This->pParser->m_pAllocator,&This->pParser->m_propAlloc,&pAllocActual);
747 if ( FAILED(hr) )
748 return hr;
749 IMemAllocator_Release(This->pParser->m_pAllocator);
750 This->pParser->m_pAllocator = pAllocActual;
752 /* create output pins. */
753 for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
755 pwszOutPinName = This->pParser->m_pHandler->pGetOutPinName(This->pParser,nIndex);
756 if ( pwszOutPinName == NULL )
757 return E_FAIL;
758 hr = QUARTZ_CreateParserOutPin(
759 This->pParser,
760 &This->pParser->m_csParser,
761 &This->pParser->m_ppOutPins[nIndex],
762 nIndex, pwszOutPinName );
763 if ( SUCCEEDED(hr) )
764 hr = QUARTZ_CompList_AddTailComp(
765 This->pParser->basefilter.pOutPins,
766 (IUnknown*)&(This->pParser->m_ppOutPins[nIndex]->pin),
767 NULL, 0 );
768 if ( FAILED(hr) )
769 return hr;
770 pmt = &This->pParser->m_ppOutPins[nIndex]->m_mtOut;
771 QUARTZ_MediaType_Free( pmt );
772 ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
773 hr = This->pParser->m_pHandler->pGetStreamType(This->pParser,nIndex,pmt);
774 if ( FAILED(hr) )
776 ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
777 return hr;
779 This->pParser->m_ppOutPins[nIndex]->pin.cAcceptTypes = 1;
780 This->pParser->m_ppOutPins[nIndex]->pin.pmtAcceptTypes = pmt;
783 return NOERROR;
786 static HRESULT CParserInPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
788 CParserInPinImpl_THIS(pImpl,pin);
790 CParserImpl_OnInactive(&This->pParser->basefilter);
791 CParserImpl_OnStop(&This->pParser->basefilter);
792 if ( This->pParser->m_pHandler->pUninitParser != NULL )
793 This->pParser->m_pHandler->pUninitParser(This->pParser);
794 CParserImpl_SetAsyncReader( This->pParser, NULL );
795 if ( This->pParser->m_pAllocator != NULL )
797 IMemAllocator_Decommit(This->pParser->m_pAllocator);
798 IMemAllocator_Release(This->pParser->m_pAllocator);
799 This->pParser->m_pAllocator = NULL;
802 return NOERROR;
805 static HRESULT CParserInPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
807 CParserInPinImpl_THIS(pImpl,pin);
809 TRACE("(%p,%p)\n",This,pmt);
811 if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Stream ) )
812 return E_FAIL;
814 return NOERROR;
817 static const CBasePinHandlers inputpinhandlers =
819 CParserInPinImpl_OnPreConnect, /* pOnPreConnect */
820 NULL, /* pOnPostConnect */
821 CParserInPinImpl_OnDisconnect, /* pOnDisconnect */
822 CParserInPinImpl_CheckMediaType, /* pCheckMediaType */
823 NULL, /* pQualityNotify */
824 NULL, /* pReceive */
825 NULL, /* pReceiveCanBlock */
826 NULL, /* pEndOfStream */
827 NULL, /* pBeginFlush */
828 NULL, /* pEndFlush */
829 NULL, /* pNewSegment */
832 /***************************************************************************
834 * CParserOutPinImpl methods
838 static HRESULT CParserOutPinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPin )
840 CParserOutPinImpl_THIS(pImpl,pin);
841 ALLOCATOR_PROPERTIES propReq;
842 ALLOCATOR_PROPERTIES propActual;
843 IMemAllocator* pAllocator;
844 HRESULT hr;
845 BOOL bNewAllocator = FALSE;
847 TRACE("(%p,%p)\n",This,pPin);
849 if ( This->pin.pMemInputPinConnectedTo == NULL )
850 return E_UNEXPECTED;
852 if ( This->m_pOutPinAllocator != NULL )
854 IMemAllocator_Release(This->m_pOutPinAllocator);
855 This->m_pOutPinAllocator = NULL;
858 /* try to use This->pParser->m_pAllocator. */
859 ZeroMemory( &propReq, sizeof(ALLOCATOR_PROPERTIES) );
860 hr = IMemInputPin_GetAllocatorRequirements(
861 This->pin.pMemInputPinConnectedTo, &propReq );
862 if ( propReq.cbAlign != 0 )
864 if ( This->pParser->m_propAlloc.cbAlign != ( This->pParser->m_propAlloc.cbAlign / propReq.cbAlign * propReq.cbAlign ) )
865 bNewAllocator = TRUE;
867 if ( propReq.cbPrefix != 0 )
868 bNewAllocator = TRUE;
869 if ( !bNewAllocator )
871 hr = IMemInputPin_NotifyAllocator(
872 This->pin.pMemInputPinConnectedTo,
873 This->pParser->m_pAllocator, FALSE );
874 if ( hr == NOERROR )
876 This->m_pOutPinAllocator = This->pParser->m_pAllocator;
877 IMemAllocator_AddRef(This->m_pOutPinAllocator);
878 return NOERROR;
882 hr = IMemInputPin_GetAllocator(
883 This->pin.pMemInputPinConnectedTo, &pAllocator );
884 if ( FAILED(hr) )
885 return hr;
886 hr = IMemAllocator_SetProperties( pAllocator, &This->pParser->m_propAlloc, &propActual );
887 if ( SUCCEEDED(hr) )
888 hr = IMemInputPin_NotifyAllocator(
889 This->pin.pMemInputPinConnectedTo, pAllocator, FALSE );
890 if ( FAILED(hr) )
892 IMemAllocator_Release(pAllocator);
893 return hr;
896 This->m_pOutPinAllocator = pAllocator;
897 return NOERROR;
900 static HRESULT CParserOutPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
902 CParserOutPinImpl_THIS(pImpl,pin);
904 if ( This->m_pOutPinAllocator != NULL )
906 IMemAllocator_Release(This->m_pOutPinAllocator);
907 This->m_pOutPinAllocator = NULL;
910 return NOERROR;
913 static HRESULT CParserOutPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
915 CParserOutPinImpl_THIS(pImpl,pin);
916 HRESULT hr;
918 TRACE("(%p,%p)\n",This,pmt);
919 if ( pmt == NULL )
920 return E_POINTER;
922 if ( This->pParser->m_pHandler->pCheckStreamType == NULL )
923 return E_NOTIMPL;
925 hr = This->pParser->m_pHandler->pCheckStreamType( This->pParser, This->nStreamIndex, pmt );
926 if ( FAILED(hr) )
927 return hr;
929 return NOERROR;
933 static const CBasePinHandlers outputpinhandlers =
935 NULL, /* pOnPreConnect */
936 CParserOutPinImpl_OnPostConnect, /* pOnPostConnect */
937 CParserOutPinImpl_OnDisconnect, /* pOnDisconnect */
938 CParserOutPinImpl_CheckMediaType, /* pCheckMediaType */
939 NULL, /* pQualityNotify */
940 OutputPinSync_Receive, /* pReceive */
941 OutputPinSync_ReceiveCanBlock, /* pReceiveCanBlock */
942 OutputPinSync_EndOfStream, /* pEndOfStream */
943 OutputPinSync_BeginFlush, /* pBeginFlush */
944 OutputPinSync_EndFlush, /* pEndFlush */
945 OutputPinSync_NewSegment, /* pNewSegment */
948 /***************************************************************************
950 * new/delete CParserImpl
954 /* can I use offsetof safely? - FIXME? */
955 static QUARTZ_IFEntry FilterIFEntries[] =
957 { &IID_IPersist, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
958 { &IID_IMediaFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
959 { &IID_IBaseFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
962 static void QUARTZ_DestroyParser(IUnknown* punk)
964 CParserImpl_THIS(punk,unk);
966 TRACE( "(%p)\n", This );
968 if ( This->m_pInPin != NULL )
969 CParserInPinImpl_OnDisconnect(&This->m_pInPin->pin);
971 CParserImpl_SetAsyncReader( This, NULL );
972 if ( This->m_pAllocator != NULL )
974 IMemAllocator_Release(This->m_pAllocator);
975 This->m_pAllocator = NULL;
977 if ( This->m_pInPin != NULL )
979 IUnknown_Release(This->m_pInPin->unk.punkControl);
980 This->m_pInPin = NULL;
982 CParserImpl_ReleaseOutPins( This );
984 DeleteCriticalSection( &This->m_csParser );
986 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
989 HRESULT QUARTZ_CreateParser(
990 IUnknown* punkOuter,void** ppobj,
991 const CLSID* pclsidParser,
992 LPCWSTR pwszParserName,
993 LPCWSTR pwszInPinName,
994 const ParserHandlers* pHandler )
996 CParserImpl* This = NULL;
997 HRESULT hr;
999 TRACE("(%p,%p)\n",punkOuter,ppobj);
1001 This = (CParserImpl*)
1002 QUARTZ_AllocObj( sizeof(CParserImpl) );
1003 if ( This == NULL )
1004 return E_OUTOFMEMORY;
1005 ZeroMemory( This, sizeof(CParserImpl) );
1007 This->m_pInPin = NULL;
1008 This->m_cOutStreams = 0;
1009 This->m_ppOutPins = NULL;
1010 This->m_pReader = NULL;
1011 This->m_pAllocator = NULL;
1012 ZeroMemory( &This->m_propAlloc, sizeof(ALLOCATOR_PROPERTIES) );
1013 This->m_hEventInit = (HANDLE)NULL;
1014 This->m_hThread = (HANDLE)NULL;
1015 This->m_dwThreadId = 0;
1016 This->m_bSendEOS = FALSE;
1017 This->m_pHandler = pHandler;
1018 This->m_pUserData = NULL;
1020 QUARTZ_IUnkInit( &This->unk, punkOuter );
1022 hr = CBaseFilterImpl_InitIBaseFilter(
1023 &This->basefilter,
1024 This->unk.punkControl,
1025 pclsidParser,
1026 pwszParserName,
1027 &filterhandlers );
1028 if ( SUCCEEDED(hr) )
1030 /* construct this class. */
1031 hr = S_OK;
1033 if ( FAILED(hr) )
1035 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
1039 if ( FAILED(hr) )
1041 QUARTZ_FreeObj(This);
1042 return hr;
1045 This->unk.pEntries = FilterIFEntries;
1046 This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
1047 This->unk.pOnFinalRelease = QUARTZ_DestroyParser;
1048 InitializeCriticalSection( &This->m_csParser );
1050 /* create the input pin. */
1051 hr = QUARTZ_CreateParserInPin(
1052 This,
1053 &This->m_csParser,
1054 &This->m_pInPin,
1055 pwszInPinName );
1056 if ( SUCCEEDED(hr) )
1057 hr = QUARTZ_CompList_AddComp(
1058 This->basefilter.pInPins,
1059 (IUnknown*)&(This->m_pInPin->pin),
1060 NULL, 0 );
1062 if ( FAILED(hr) )
1064 IUnknown_Release( This->unk.punkControl );
1065 return hr;
1068 *ppobj = (void*)&(This->unk);
1070 return S_OK;
1073 /***************************************************************************
1075 * new/delete CParserInPinImpl
1079 /* can I use offsetof safely? - FIXME? */
1080 static QUARTZ_IFEntry InPinIFEntries[] =
1082 { &IID_IPin, offsetof(CParserInPinImpl,pin)-offsetof(CParserInPinImpl,unk) },
1083 { &IID_IMemInputPin, offsetof(CParserInPinImpl,meminput)-offsetof(CParserInPinImpl,unk) },
1086 static void QUARTZ_DestroyParserInPin(IUnknown* punk)
1088 CParserInPinImpl_THIS(punk,unk);
1090 TRACE( "(%p)\n", This );
1092 CPinBaseImpl_UninitIPin( &This->pin );
1093 CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
1096 HRESULT QUARTZ_CreateParserInPin(
1097 CParserImpl* pFilter,
1098 CRITICAL_SECTION* pcsPin,
1099 CParserInPinImpl** ppPin,
1100 LPCWSTR pwszPinName )
1102 CParserInPinImpl* This = NULL;
1103 HRESULT hr;
1105 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
1107 This = (CParserInPinImpl*)
1108 QUARTZ_AllocObj( sizeof(CParserInPinImpl) );
1109 if ( This == NULL )
1110 return E_OUTOFMEMORY;
1112 QUARTZ_IUnkInit( &This->unk, NULL );
1113 This->pParser = pFilter;
1115 hr = CPinBaseImpl_InitIPin(
1116 &This->pin,
1117 This->unk.punkControl,
1118 pcsPin,
1119 &pFilter->basefilter,
1120 pwszPinName,
1121 FALSE,
1122 &inputpinhandlers );
1124 if ( SUCCEEDED(hr) )
1126 hr = CMemInputPinBaseImpl_InitIMemInputPin(
1127 &This->meminput,
1128 This->unk.punkControl,
1129 &This->pin );
1130 if ( FAILED(hr) )
1132 CPinBaseImpl_UninitIPin( &This->pin );
1136 if ( FAILED(hr) )
1138 QUARTZ_FreeObj(This);
1139 return hr;
1142 This->unk.pEntries = InPinIFEntries;
1143 This->unk.dwEntries = sizeof(InPinIFEntries)/sizeof(InPinIFEntries[0]);
1144 This->unk.pOnFinalRelease = QUARTZ_DestroyParserInPin;
1146 *ppPin = This;
1148 TRACE("returned successfully.\n");
1150 return S_OK;
1154 /***************************************************************************
1156 * new/delete CParserOutPinImpl
1160 /* can I use offsetof safely? - FIXME? */
1161 static QUARTZ_IFEntry OutPinIFEntries[] =
1163 { &IID_IPin, offsetof(CParserOutPinImpl,pin)-offsetof(CParserOutPinImpl,unk) },
1164 { &IID_IQualityControl, offsetof(CParserOutPinImpl,qcontrol)-offsetof(CParserOutPinImpl,unk) },
1165 { &IID_IMediaSeeking, offsetof(CParserOutPinImpl,mediaseeking)-offsetof(CParserOutPinImpl,unk) },
1166 { &IID_IMediaPosition, offsetof(CParserOutPinImpl,mediaposition)-offsetof(CParserOutPinImpl,unk) },
1169 static void QUARTZ_DestroyParserOutPin(IUnknown* punk)
1171 CParserOutPinImpl_THIS(punk,unk);
1173 TRACE( "(%p)\n", This );
1175 QUARTZ_MediaType_Free( &This->m_mtOut );
1176 if ( This->m_pOutPinAllocator != NULL )
1177 IMemAllocator_Release(This->m_pOutPinAllocator);
1179 CParserOutPinImpl_UninitIMediaPosition(This);
1180 CParserOutPinImpl_UninitIMediaSeeking(This);
1181 CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
1182 CPinBaseImpl_UninitIPin( &This->pin );
1186 HRESULT QUARTZ_CreateParserOutPin(
1187 CParserImpl* pFilter,
1188 CRITICAL_SECTION* pcsPin,
1189 CParserOutPinImpl** ppPin,
1190 ULONG nStreamIndex,
1191 LPCWSTR pwszPinName )
1193 CParserOutPinImpl* This = NULL;
1194 HRESULT hr;
1196 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
1198 This = (CParserOutPinImpl*)
1199 QUARTZ_AllocObj( sizeof(CParserOutPinImpl) );
1200 if ( This == NULL )
1201 return E_OUTOFMEMORY;
1203 QUARTZ_IUnkInit( &This->unk, NULL );
1204 This->pParser = pFilter;
1205 This->nStreamIndex = nStreamIndex;
1206 ZeroMemory( &This->m_mtOut, sizeof(AM_MEDIA_TYPE) );
1207 This->m_pOutPinAllocator = NULL;
1208 This->m_pUserData = NULL;
1209 This->m_bReqUsed = FALSE;
1210 This->m_pReqSample = NULL;
1211 This->m_llReqStart = 0;
1212 This->m_lReqLength = 0;
1213 This->m_rtReqStart = 0;
1214 This->m_rtReqStop = 0;
1217 hr = CPinBaseImpl_InitIPin(
1218 &This->pin,
1219 This->unk.punkControl,
1220 pcsPin,
1221 &pFilter->basefilter,
1222 pwszPinName,
1223 TRUE,
1224 &outputpinhandlers );
1226 if ( SUCCEEDED(hr) )
1228 hr = CQualityControlPassThruImpl_InitIQualityControl(
1229 &This->qcontrol,
1230 This->unk.punkControl,
1231 &This->pin );
1232 if ( SUCCEEDED(hr) )
1234 hr = CParserOutPinImpl_InitIMediaSeeking(This);
1235 if ( SUCCEEDED(hr) )
1237 hr = CParserOutPinImpl_InitIMediaPosition(This);
1238 if ( FAILED(hr) )
1240 CParserOutPinImpl_UninitIMediaSeeking(This);
1243 if ( FAILED(hr) )
1245 CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
1248 if ( FAILED(hr) )
1250 CPinBaseImpl_UninitIPin( &This->pin );
1254 if ( FAILED(hr) )
1256 QUARTZ_FreeObj(This);
1257 return hr;
1260 This->unk.pEntries = OutPinIFEntries;
1261 This->unk.dwEntries = sizeof(OutPinIFEntries)/sizeof(OutPinIFEntries[0]);
1262 This->unk.pOnFinalRelease = QUARTZ_DestroyParserOutPin;
1264 *ppPin = This;
1266 TRACE("returned successfully.\n");
1268 return S_OK;
1272 /***************************************************************************
1274 * IMediaSeeking for CParserOutPinImpl
1278 static HRESULT WINAPI
1279 IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj)
1281 CParserOutPinImpl_THIS(iface,mediaseeking);
1283 TRACE("(%p)->()\n",This);
1285 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
1288 static ULONG WINAPI
1289 IMediaSeeking_fnAddRef(IMediaSeeking* iface)
1291 CParserOutPinImpl_THIS(iface,mediaseeking);
1293 TRACE("(%p)->()\n",This);
1295 return IUnknown_AddRef(This->unk.punkControl);
1298 static ULONG WINAPI
1299 IMediaSeeking_fnRelease(IMediaSeeking* iface)
1301 CParserOutPinImpl_THIS(iface,mediaseeking);
1303 TRACE("(%p)->()\n",This);
1305 return IUnknown_Release(This->unk.punkControl);
1309 static HRESULT WINAPI
1310 IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
1312 CParserOutPinImpl_THIS(iface,mediaseeking);
1314 FIXME("(%p)->() stub!\n",This);
1316 return E_NOTIMPL;
1319 static HRESULT WINAPI
1320 IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
1322 CParserOutPinImpl_THIS(iface,mediaseeking);
1324 FIXME("(%p)->() stub!\n",This);
1326 return E_NOTIMPL;
1329 static HRESULT WINAPI
1330 IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat)
1332 CParserOutPinImpl_THIS(iface,mediaseeking);
1334 FIXME("(%p)->() stub!\n",This);
1336 return E_NOTIMPL;
1339 static HRESULT WINAPI
1340 IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat)
1342 CParserOutPinImpl_THIS(iface,mediaseeking);
1344 FIXME("(%p)->() stub!\n",This);
1346 return E_NOTIMPL;
1349 static HRESULT WINAPI
1350 IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat)
1352 CParserOutPinImpl_THIS(iface,mediaseeking);
1354 FIXME("(%p)->() stub!\n",This);
1356 return E_NOTIMPL;
1359 static HRESULT WINAPI
1360 IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
1362 CParserOutPinImpl_THIS(iface,mediaseeking);
1364 FIXME("(%p)->() stub!\n",This);
1366 return E_NOTIMPL;
1369 static HRESULT WINAPI
1370 IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
1372 CParserOutPinImpl_THIS(iface,mediaseeking);
1374 FIXME("(%p)->() stub!\n",This);
1376 return E_NOTIMPL;
1379 static HRESULT WINAPI
1380 IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
1382 CParserOutPinImpl_THIS(iface,mediaseeking);
1384 /* the following line may produce too many FIXMEs... */
1385 FIXME("(%p)->() stub!\n",This);
1387 return E_NOTIMPL;
1390 static HRESULT WINAPI
1391 IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos)
1393 CParserOutPinImpl_THIS(iface,mediaseeking);
1395 FIXME("(%p)->() stub!\n",This);
1397 return E_NOTIMPL;
1400 static HRESULT WINAPI
1401 IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos)
1403 CParserOutPinImpl_THIS(iface,mediaseeking);
1405 FIXME("(%p)->() stub!\n",This);
1407 return E_NOTIMPL;
1410 static HRESULT WINAPI
1411 IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn)
1413 CParserOutPinImpl_THIS(iface,mediaseeking);
1415 FIXME("(%p)->() stub!\n",This);
1417 return E_NOTIMPL;
1420 static HRESULT WINAPI
1421 IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags)
1423 CParserOutPinImpl_THIS(iface,mediaseeking);
1425 FIXME("(%p)->() stub!\n",This);
1427 return E_NOTIMPL;
1430 static HRESULT WINAPI
1431 IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop)
1433 CParserOutPinImpl_THIS(iface,mediaseeking);
1435 FIXME("(%p)->() stub!\n",This);
1437 return E_NOTIMPL;
1440 static HRESULT WINAPI
1441 IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast)
1443 CParserOutPinImpl_THIS(iface,mediaseeking);
1445 FIXME("(%p)->() stub!\n",This);
1447 return E_NOTIMPL;
1450 static HRESULT WINAPI
1451 IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate)
1453 CParserOutPinImpl_THIS(iface,mediaseeking);
1455 FIXME("(%p)->() stub!\n",This);
1457 return E_NOTIMPL;
1460 static HRESULT WINAPI
1461 IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate)
1463 CParserOutPinImpl_THIS(iface,mediaseeking);
1465 FIXME("(%p)->() stub!\n",This);
1467 return E_NOTIMPL;
1470 static HRESULT WINAPI
1471 IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll)
1473 CParserOutPinImpl_THIS(iface,mediaseeking);
1475 FIXME("(%p)->() stub!\n",This);
1477 return E_NOTIMPL;
1483 static ICOM_VTABLE(IMediaSeeking) imediaseeking =
1485 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1486 /* IUnknown fields */
1487 IMediaSeeking_fnQueryInterface,
1488 IMediaSeeking_fnAddRef,
1489 IMediaSeeking_fnRelease,
1490 /* IMediaSeeking fields */
1491 IMediaSeeking_fnGetCapabilities,
1492 IMediaSeeking_fnCheckCapabilities,
1493 IMediaSeeking_fnIsFormatSupported,
1494 IMediaSeeking_fnQueryPreferredFormat,
1495 IMediaSeeking_fnGetTimeFormat,
1496 IMediaSeeking_fnIsUsingTimeFormat,
1497 IMediaSeeking_fnSetTimeFormat,
1498 IMediaSeeking_fnGetDuration,
1499 IMediaSeeking_fnGetStopPosition,
1500 IMediaSeeking_fnGetCurrentPosition,
1501 IMediaSeeking_fnConvertTimeFormat,
1502 IMediaSeeking_fnSetPositions,
1503 IMediaSeeking_fnGetPositions,
1504 IMediaSeeking_fnGetAvailable,
1505 IMediaSeeking_fnSetRate,
1506 IMediaSeeking_fnGetRate,
1507 IMediaSeeking_fnGetPreroll,
1510 HRESULT CParserOutPinImpl_InitIMediaSeeking( CParserOutPinImpl* This )
1512 TRACE("(%p)\n",This);
1513 ICOM_VTBL(&This->mediaseeking) = &imediaseeking;
1515 return NOERROR;
1518 void CParserOutPinImpl_UninitIMediaSeeking( CParserOutPinImpl* This )
1520 TRACE("(%p)\n",This);
1523 /***************************************************************************
1525 * IMediaPosition for CParserOutPinImpl
1529 static HRESULT WINAPI
1530 IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj)
1532 CParserOutPinImpl_THIS(iface,mediaposition);
1534 TRACE("(%p)->()\n",This);
1536 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
1539 static ULONG WINAPI
1540 IMediaPosition_fnAddRef(IMediaPosition* iface)
1542 CParserOutPinImpl_THIS(iface,mediaposition);
1544 TRACE("(%p)->()\n",This);
1546 return IUnknown_AddRef(This->unk.punkControl);
1549 static ULONG WINAPI
1550 IMediaPosition_fnRelease(IMediaPosition* iface)
1552 CParserOutPinImpl_THIS(iface,mediaposition);
1554 TRACE("(%p)->()\n",This);
1556 return IUnknown_Release(This->unk.punkControl);
1559 static HRESULT WINAPI
1560 IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo)
1562 CParserOutPinImpl_THIS(iface,mediaposition);
1564 FIXME("(%p)->() stub!\n",This);
1566 return E_NOTIMPL;
1569 static HRESULT WINAPI
1570 IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
1572 CParserOutPinImpl_THIS(iface,mediaposition);
1574 FIXME("(%p)->() stub!\n",This);
1576 return E_NOTIMPL;
1579 static HRESULT WINAPI
1580 IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
1582 CParserOutPinImpl_THIS(iface,mediaposition);
1584 FIXME("(%p)->() stub!\n",This);
1586 return E_NOTIMPL;
1589 static HRESULT WINAPI
1590 IMediaPosition_fnInvoke(IMediaPosition* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1592 CParserOutPinImpl_THIS(iface,mediaposition);
1594 FIXME("(%p)->() stub!\n",This);
1596 return E_NOTIMPL;
1600 static HRESULT WINAPI
1601 IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
1603 CParserOutPinImpl_THIS(iface,mediaposition);
1605 FIXME("(%p)->() stub!\n",This);
1607 return E_NOTIMPL;
1610 static HRESULT WINAPI
1611 IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
1613 CParserOutPinImpl_THIS(iface,mediaposition);
1615 FIXME("(%p)->() stub!\n",This);
1617 return E_NOTIMPL;
1620 static HRESULT WINAPI
1621 IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
1623 CParserOutPinImpl_THIS(iface,mediaposition);
1625 FIXME("(%p)->() stub!\n",This);
1627 return E_NOTIMPL;
1630 static HRESULT WINAPI
1631 IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
1633 CParserOutPinImpl_THIS(iface,mediaposition);
1635 FIXME("(%p)->() stub!\n",This);
1637 return E_NOTIMPL;
1640 static HRESULT WINAPI
1641 IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
1643 CParserOutPinImpl_THIS(iface,mediaposition);
1645 FIXME("(%p)->() stub!\n",This);
1647 return E_NOTIMPL;
1650 static HRESULT WINAPI
1651 IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
1653 CParserOutPinImpl_THIS(iface,mediaposition);
1655 FIXME("(%p)->() stub!\n",This);
1657 return E_NOTIMPL;
1660 static HRESULT WINAPI
1661 IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
1663 CParserOutPinImpl_THIS(iface,mediaposition);
1665 FIXME("(%p)->() stub!\n",This);
1667 return E_NOTIMPL;
1670 static HRESULT WINAPI
1671 IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
1673 CParserOutPinImpl_THIS(iface,mediaposition);
1675 return IMediaSeeking_SetRate(CParserOutPinImpl_IMediaSeeking(This),dblRate);
1678 static HRESULT WINAPI
1679 IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
1681 CParserOutPinImpl_THIS(iface,mediaposition);
1683 return IMediaSeeking_GetRate(CParserOutPinImpl_IMediaSeeking(This),pdblRate);
1686 static HRESULT WINAPI
1687 IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
1689 CParserOutPinImpl_THIS(iface,mediaposition);
1691 FIXME("(%p)->() stub!\n",This);
1693 return E_NOTIMPL;
1696 static HRESULT WINAPI
1697 IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
1699 CParserOutPinImpl_THIS(iface,mediaposition);
1701 FIXME("(%p)->() stub!\n",This);
1703 return E_NOTIMPL;
1707 static ICOM_VTABLE(IMediaPosition) imediaposition =
1709 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1710 /* IUnknown fields */
1711 IMediaPosition_fnQueryInterface,
1712 IMediaPosition_fnAddRef,
1713 IMediaPosition_fnRelease,
1714 /* IDispatch fields */
1715 IMediaPosition_fnGetTypeInfoCount,
1716 IMediaPosition_fnGetTypeInfo,
1717 IMediaPosition_fnGetIDsOfNames,
1718 IMediaPosition_fnInvoke,
1719 /* IMediaPosition fields */
1720 IMediaPosition_fnget_Duration,
1721 IMediaPosition_fnput_CurrentPosition,
1722 IMediaPosition_fnget_CurrentPosition,
1723 IMediaPosition_fnget_StopTime,
1724 IMediaPosition_fnput_StopTime,
1725 IMediaPosition_fnget_PrerollTime,
1726 IMediaPosition_fnput_PrerollTime,
1727 IMediaPosition_fnput_Rate,
1728 IMediaPosition_fnget_Rate,
1729 IMediaPosition_fnCanSeekForward,
1730 IMediaPosition_fnCanSeekBackward,
1734 HRESULT CParserOutPinImpl_InitIMediaPosition( CParserOutPinImpl* This )
1736 TRACE("(%p)\n",This);
1737 ICOM_VTBL(&This->mediaposition) = &imediaposition;
1739 return NOERROR;
1742 void CParserOutPinImpl_UninitIMediaPosition( CParserOutPinImpl* This )
1744 TRACE("(%p)\n",This);