2 * Implements Asynchronous File/URL Source.
4 * FIXME - not work yet.
6 * hidenori@a2.ctktv.ne.jp
16 #include "wine/obj_base.h"
21 #include "debugtools.h"
22 DEFAULT_DEBUG_CHANNEL(quartz
);
24 #include "quartz_private.h"
29 /***************************************************************************
31 * CAsyncReaderImpl internal methods
36 CAsyncReaderImpl_ThreadEntry( LPVOID pv
)
38 CAsyncReaderImpl
* This
= (CAsyncReaderImpl
*)pv
;
39 HANDLE hWaitEvents
[2];
40 HANDLE hReadEvents
[2];
43 SetEvent( This
->m_hEventInit
);
45 hWaitEvents
[0] = This
->m_hEventReqQueued
;
46 hWaitEvents
[1] = This
->m_hEventAbort
;
48 hReadEvents
[0] = This
->m_hEventSampQueued
;
49 hReadEvents
[1] = This
->m_hEventAbort
;
53 dwRes
= WaitForMultipleObjects(2,hWaitEvents
,FALSE
,INFINITE
);
54 if ( dwRes
!= WAIT_OBJECT_0
)
57 /* FIXME - process a queued request */
59 dwRes
= WaitForMultipleObjects(2,hReadEvents
,FALSE
,INFINITE
);
60 if ( dwRes
!= WAIT_OBJECT_0
)
68 CAsyncReaderImpl_BeginThread( CAsyncReaderImpl
* This
)
74 if ( This
->m_hEventInit
!= (HANDLE
)NULL
||
75 This
->m_hEventAbort
!= (HANDLE
)NULL
||
76 This
->m_hEventReqQueued
!= (HANDLE
)NULL
||
77 This
->m_hEventSampQueued
!= (HANDLE
)NULL
||
78 This
->m_hEventCompletion
!= (HANDLE
)NULL
||
79 This
->m_hThread
!= (HANDLE
)NULL
)
82 This
->m_hEventInit
= CreateEventA(NULL
,TRUE
,FALSE
,NULL
);
83 if ( This
->m_hEventInit
== (HANDLE
)NULL
)
85 This
->m_hEventAbort
= CreateEventA(NULL
,TRUE
,FALSE
,NULL
);
86 if ( This
->m_hEventAbort
== (HANDLE
)NULL
)
88 This
->m_hEventReqQueued
= CreateEventA(NULL
,TRUE
,FALSE
,NULL
);
89 if ( This
->m_hEventReqQueued
== (HANDLE
)NULL
)
91 This
->m_hEventSampQueued
= CreateEventA(NULL
,TRUE
,FALSE
,NULL
);
92 if ( This
->m_hEventSampQueued
== (HANDLE
)NULL
)
94 This
->m_hEventCompletion
= CreateEventA(NULL
,TRUE
,FALSE
,NULL
);
95 if ( This
->m_hEventCompletion
== (HANDLE
)NULL
)
98 /* create the processing thread. */
99 This
->m_hThread
= CreateThread(
101 CAsyncReaderImpl_ThreadEntry
,
104 if ( This
->m_hThread
== (HANDLE
)NULL
)
107 hEvents
[0] = This
->m_hEventInit
;
108 hEvents
[1] = This
->m_hThread
;
110 dwRes
= WaitForMultipleObjects(2,hEvents
,FALSE
,INFINITE
);
111 if ( dwRes
!= WAIT_OBJECT_0
)
118 CAsyncReaderImpl_EndThread( CAsyncReaderImpl
* This
)
120 if ( This
->m_hThread
!= (HANDLE
)NULL
)
122 SetEvent( This
->m_hEventAbort
);
124 WaitForSingleObject( This
->m_hThread
, INFINITE
);
125 CloseHandle( This
->m_hThread
);
126 This
->m_hThread
= (HANDLE
)NULL
;
128 if ( This
->m_hEventInit
!= (HANDLE
)NULL
)
130 CloseHandle( This
->m_hEventInit
);
131 This
->m_hEventInit
= (HANDLE
)NULL
;
133 if ( This
->m_hEventAbort
!= (HANDLE
)NULL
)
135 CloseHandle( This
->m_hEventAbort
);
136 This
->m_hEventAbort
= (HANDLE
)NULL
;
138 if ( This
->m_hEventReqQueued
!= (HANDLE
)NULL
)
140 CloseHandle( This
->m_hEventReqQueued
);
141 This
->m_hEventReqQueued
= (HANDLE
)NULL
;
143 if ( This
->m_hEventSampQueued
!= (HANDLE
)NULL
)
145 CloseHandle( This
->m_hEventSampQueued
);
146 This
->m_hEventSampQueued
= (HANDLE
)NULL
;
148 if ( This
->m_hEventCompletion
!= (HANDLE
)NULL
)
150 CloseHandle( This
->m_hEventCompletion
);
151 This
->m_hEventCompletion
= (HANDLE
)NULL
;
155 /***************************************************************************
157 * CAsyncReaderImpl methods
161 static HRESULT WINAPI
162 CAsyncReaderImpl_fnQueryInterface(IAsyncReader
* iface
,REFIID riid
,void** ppobj
)
164 ICOM_THIS(CAsyncReaderImpl
,iface
);
166 TRACE("(%p)->()\n",This
);
168 return IUnknown_QueryInterface(This
->punkControl
,riid
,ppobj
);
172 CAsyncReaderImpl_fnAddRef(IAsyncReader
* iface
)
174 ICOM_THIS(CAsyncReaderImpl
,iface
);
176 TRACE("(%p)->()\n",This
);
178 return IUnknown_AddRef(This
->punkControl
);
182 CAsyncReaderImpl_fnRelease(IAsyncReader
* iface
)
184 ICOM_THIS(CAsyncReaderImpl
,iface
);
186 TRACE("(%p)->()\n",This
);
188 return IUnknown_Release(This
->punkControl
);
191 static HRESULT WINAPI
192 CAsyncReaderImpl_fnRequestAllocator(IAsyncReader
* iface
,IMemAllocator
* pAlloc
,ALLOCATOR_PROPERTIES
* pProp
,IMemAllocator
** ppAllocActual
)
194 ICOM_THIS(CAsyncReaderImpl
,iface
);
196 ALLOCATOR_PROPERTIES propActual
;
197 IUnknown
* punk
= NULL
;
199 TRACE("(%p)->(%p,%p,%p)\n",This
,pAlloc
,pProp
,ppAllocActual
);
201 if ( pAlloc
== NULL
|| pProp
== NULL
|| ppAllocActual
== NULL
)
204 IMemAllocator_AddRef(pAlloc
);
205 hr
= IMemAllocator_SetProperties( pAlloc
, pProp
, &propActual
);
208 *ppAllocActual
= pAlloc
;
211 IMemAllocator_Release(pAlloc
);
213 hr
= QUARTZ_CreateMemoryAllocator(NULL
,(void**)&punk
);
216 hr
= IUnknown_QueryInterface( punk
, &IID_IMemAllocator
, (void**)&pAlloc
);
217 IUnknown_Release(punk
);
221 hr
= IMemAllocator_SetProperties( pAlloc
, pProp
, &propActual
);
224 *ppAllocActual
= pAlloc
;
227 IMemAllocator_Release(pAlloc
);
232 static HRESULT WINAPI
233 CAsyncReaderImpl_fnRequest(IAsyncReader
* iface
,IMediaSample
* pSample
,DWORD_PTR dwContext
)
235 ICOM_THIS(CAsyncReaderImpl
,iface
);
237 FIXME("(%p)->() stub!\n",This
);
239 EnterCriticalSection( This
->pcsReader
);
240 LeaveCriticalSection( This
->pcsReader
);
245 static HRESULT WINAPI
246 CAsyncReaderImpl_fnWaitForNext(IAsyncReader
* iface
,DWORD dwTimeout
,IMediaSample
** pSample
,DWORD_PTR
* pdwContext
)
248 ICOM_THIS(CAsyncReaderImpl
,iface
);
250 FIXME("(%p)->() stub!\n",This
);
252 EnterCriticalSection( This
->pcsReader
);
253 LeaveCriticalSection( This
->pcsReader
);
258 static HRESULT WINAPI
259 CAsyncReaderImpl_fnSyncReadAligned(IAsyncReader
* iface
,IMediaSample
* pSample
)
261 ICOM_THIS(CAsyncReaderImpl
,iface
);
263 FIXME("(%p)->() stub!\n",This
);
265 EnterCriticalSection( This
->pcsReader
);
266 LeaveCriticalSection( This
->pcsReader
);
271 static HRESULT WINAPI
272 CAsyncReaderImpl_fnSyncRead(IAsyncReader
* iface
,LONGLONG llPosStart
,LONG lLength
,BYTE
* pbBuf
)
274 ICOM_THIS(CAsyncReaderImpl
,iface
);
276 FIXME("(%p)->() stub!\n",This
);
278 EnterCriticalSection( This
->pcsReader
);
279 LeaveCriticalSection( This
->pcsReader
);
284 static HRESULT WINAPI
285 CAsyncReaderImpl_fnLength(IAsyncReader
* iface
,LONGLONG
* pllTotal
,LONGLONG
* pllAvailable
)
287 ICOM_THIS(CAsyncReaderImpl
,iface
);
290 TRACE("(%p)->()\n",This
);
292 EnterCriticalSection( This
->pcsReader
);
293 hr
= This
->pSource
->m_pHandler
->pGetLength( This
->pSource
, pllTotal
, pllAvailable
);
294 LeaveCriticalSection( This
->pcsReader
);
299 static HRESULT WINAPI
300 CAsyncReaderImpl_fnBeginFlush(IAsyncReader
* iface
)
302 ICOM_THIS(CAsyncReaderImpl
,iface
);
304 FIXME("(%p)->() stub!\n",This
);
306 EnterCriticalSection( This
->pcsReader
);
307 LeaveCriticalSection( This
->pcsReader
);
312 static HRESULT WINAPI
313 CAsyncReaderImpl_fnEndFlush(IAsyncReader
* iface
)
315 ICOM_THIS(CAsyncReaderImpl
,iface
);
317 FIXME("(%p)->() stub!\n",This
);
319 EnterCriticalSection( This
->pcsReader
);
320 LeaveCriticalSection( This
->pcsReader
);
326 static ICOM_VTABLE(IAsyncReader
) iasyncreader
=
328 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
329 /* IUnknown fields */
330 CAsyncReaderImpl_fnQueryInterface
,
331 CAsyncReaderImpl_fnAddRef
,
332 CAsyncReaderImpl_fnRelease
,
334 /* IAsyncReader fields */
335 CAsyncReaderImpl_fnRequestAllocator
,
336 CAsyncReaderImpl_fnRequest
,
337 CAsyncReaderImpl_fnWaitForNext
,
338 CAsyncReaderImpl_fnSyncReadAligned
,
339 CAsyncReaderImpl_fnSyncRead
,
340 CAsyncReaderImpl_fnLength
,
341 CAsyncReaderImpl_fnBeginFlush
,
342 CAsyncReaderImpl_fnEndFlush
,
345 HRESULT
CAsyncReaderImpl_InitIAsyncReader(
346 CAsyncReaderImpl
* This
, IUnknown
* punkControl
,
347 CAsyncSourceImpl
* pSource
,
348 CRITICAL_SECTION
* pcsReader
)
350 TRACE("(%p,%p)\n",This
,punkControl
);
352 if ( punkControl
== NULL
)
354 ERR( "punkControl must not be NULL\n" );
358 ICOM_VTBL(This
) = &iasyncreader
;
359 This
->punkControl
= punkControl
;
360 This
->pSource
= pSource
;
361 This
->pcsReader
= pcsReader
;
362 This
->m_hEventInit
= (HANDLE
)NULL
;
363 This
->m_hEventAbort
= (HANDLE
)NULL
;
364 This
->m_hEventReqQueued
= (HANDLE
)NULL
;
365 This
->m_hEventSampQueued
= (HANDLE
)NULL
;
366 This
->m_hEventCompletion
= (HANDLE
)NULL
;
367 This
->m_hThread
= (HANDLE
)NULL
;
372 void CAsyncReaderImpl_UninitIAsyncReader(
373 CAsyncReaderImpl
* This
)
375 TRACE("(%p)\n",This
);
378 /***************************************************************************
380 * CFileSourceFilterImpl
384 static HRESULT WINAPI
385 CFileSourceFilterImpl_fnQueryInterface(IFileSourceFilter
* iface
,REFIID riid
,void** ppobj
)
387 ICOM_THIS(CFileSourceFilterImpl
,iface
);
389 TRACE("(%p)->()\n",This
);
391 return IUnknown_QueryInterface(This
->punkControl
,riid
,ppobj
);
395 CFileSourceFilterImpl_fnAddRef(IFileSourceFilter
* iface
)
397 ICOM_THIS(CFileSourceFilterImpl
,iface
);
399 TRACE("(%p)->()\n",This
);
401 return IUnknown_AddRef(This
->punkControl
);
405 CFileSourceFilterImpl_fnRelease(IFileSourceFilter
* iface
)
407 ICOM_THIS(CFileSourceFilterImpl
,iface
);
409 TRACE("(%p)->()\n",This
);
411 return IUnknown_Release(This
->punkControl
);
414 static HRESULT WINAPI
415 CFileSourceFilterImpl_fnLoad(IFileSourceFilter
* iface
,LPCOLESTR pFileName
,const AM_MEDIA_TYPE
* pmt
)
417 ICOM_THIS(CFileSourceFilterImpl
,iface
);
420 TRACE("(%p)->(%s,%p)\n",This
,debugstr_w(pFileName
),pmt
);
422 if ( pFileName
== NULL
)
425 if ( This
->m_pwszFileName
!= NULL
)
428 This
->m_cbFileName
= sizeof(WCHAR
)*(lstrlenW(pFileName
)+1);
429 This
->m_pwszFileName
= (WCHAR
*)QUARTZ_AllocMem( This
->m_cbFileName
);
430 if ( This
->m_pwszFileName
== NULL
)
431 return E_OUTOFMEMORY
;
432 memcpy( This
->m_pwszFileName
, pFileName
, This
->m_cbFileName
);
436 hr
= QUARTZ_MediaType_Copy( &This
->m_mt
, pmt
);
442 ZeroMemory( &This
->m_mt
, sizeof(AM_MEDIA_TYPE
) );
443 memcpy( &This
->m_mt
.majortype
, &MEDIATYPE_Stream
, sizeof(GUID
) );
444 memcpy( &This
->m_mt
.subtype
, &MEDIASUBTYPE_NULL
, sizeof(GUID
) );
445 This
->m_mt
.lSampleSize
= 1;
446 memcpy( &This
->m_mt
.formattype
, &FORMAT_None
, sizeof(GUID
) );
449 hr
= This
->pSource
->m_pHandler
->pLoad( This
->pSource
, pFileName
);
458 static HRESULT WINAPI
459 CFileSourceFilterImpl_fnGetCurFile(IFileSourceFilter
* iface
,LPOLESTR
* ppFileName
,AM_MEDIA_TYPE
* pmt
)
461 ICOM_THIS(CFileSourceFilterImpl
,iface
);
462 HRESULT hr
= E_NOTIMPL
;
464 TRACE("(%p)->(%p,%p)\n",This
,ppFileName
,pmt
);
466 if ( ppFileName
== NULL
|| pmt
== NULL
)
469 if ( This
->m_pwszFileName
== NULL
)
472 hr
= QUARTZ_MediaType_Copy( pmt
, &This
->m_mt
);
476 *ppFileName
= (WCHAR
*)CoTaskMemAlloc( This
->m_cbFileName
);
477 if ( *ppFileName
== NULL
)
479 QUARTZ_MediaType_Free(pmt
);
480 ZeroMemory( pmt
, sizeof(AM_MEDIA_TYPE
) );
481 return E_OUTOFMEMORY
;
484 memcpy( *ppFileName
, This
->m_pwszFileName
, This
->m_cbFileName
);
489 static ICOM_VTABLE(IFileSourceFilter
) ifilesource
=
491 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
492 /* IUnknown fields */
493 CFileSourceFilterImpl_fnQueryInterface
,
494 CFileSourceFilterImpl_fnAddRef
,
495 CFileSourceFilterImpl_fnRelease
,
496 /* IFileSourceFilter fields */
497 CFileSourceFilterImpl_fnLoad
,
498 CFileSourceFilterImpl_fnGetCurFile
,
501 HRESULT
CFileSourceFilterImpl_InitIFileSourceFilter(
502 CFileSourceFilterImpl
* This
, IUnknown
* punkControl
,
503 CAsyncSourceImpl
* pSource
,
504 CRITICAL_SECTION
* pcsFileSource
)
506 TRACE("(%p,%p)\n",This
,punkControl
);
508 if ( punkControl
== NULL
)
510 ERR( "punkControl must not be NULL\n" );
514 ICOM_VTBL(This
) = &ifilesource
;
515 This
->punkControl
= punkControl
;
516 This
->pSource
= pSource
;
517 This
->pcsFileSource
= pcsFileSource
;
518 This
->m_pwszFileName
= NULL
;
519 This
->m_cbFileName
= 0;
520 ZeroMemory( &This
->m_mt
, sizeof(AM_MEDIA_TYPE
) );
525 void CFileSourceFilterImpl_UninitIFileSourceFilter(
526 CFileSourceFilterImpl
* This
)
528 TRACE("(%p)\n",This
);
530 This
->pSource
->m_pHandler
->pCleanup( This
->pSource
);
531 if ( This
->m_pwszFileName
!= NULL
)
532 QUARTZ_FreeMem( This
->m_pwszFileName
);
533 QUARTZ_MediaType_Free( &This
->m_mt
);
536 /***************************************************************************
538 * CAsyncSourcePinImpl methods
543 static HRESULT
CAsyncSourcePinImpl_OnPreConnect( CPinBaseImpl
* pImpl
, IPin
* pPin
)
545 CAsyncSourcePinImpl_THIS(pImpl
,pin
);
547 This
->bAsyncReaderQueried
= FALSE
;
552 static HRESULT
CAsyncSourcePinImpl_OnPostConnect( CPinBaseImpl
* pImpl
, IPin
* pPin
)
554 CAsyncSourcePinImpl_THIS(pImpl
,pin
);
556 if ( !This
->bAsyncReaderQueried
)
562 static HRESULT
CAsyncSourcePinImpl_OnDisconnect( CPinBaseImpl
* pImpl
)
564 CAsyncSourcePinImpl_THIS(pImpl
,pin
);
566 This
->bAsyncReaderQueried
= FALSE
;
571 static HRESULT
CAsyncSourcePinImpl_CheckMediaType( CPinBaseImpl
* pImpl
, const AM_MEDIA_TYPE
* pmt
)
573 CAsyncSourcePinImpl_THIS(pImpl
,pin
);
575 TRACE("(%p,%p)\n",This
,pmt
);
579 if ( !IsEqualGUID( &pmt
->majortype
, &MEDIATYPE_Stream
) )
585 static const CBasePinHandlers outputpinhandlers
=
587 CAsyncSourcePinImpl_OnPreConnect
, /* pOnPreConnect */
588 CAsyncSourcePinImpl_OnPostConnect
, /* pOnPostConnect */
589 CAsyncSourcePinImpl_OnDisconnect
, /* pOnDisconnect */
590 CAsyncSourcePinImpl_CheckMediaType
, /* pCheckMediaType */
591 NULL
, /* pQualityNotify */
593 NULL
, /* pReceiveCanBlock */
594 NULL
, /* pEndOfStream */
595 NULL
, /* pBeginFlush */
596 NULL
, /* pEndFlush */
597 NULL
, /* pNewSegment */
600 /***************************************************************************
602 * CAsyncSourceImpl methods
606 static HRESULT
CAsyncSourceImpl_OnActive( CBaseFilterImpl
* pImpl
)
608 CAsyncSourceImpl_THIS(pImpl
,basefilter
);
611 TRACE( "(%p)\n", This
);
613 hr
= CAsyncReaderImpl_BeginThread(&This
->pPin
->async
);
620 static HRESULT
CAsyncSourceImpl_OnInactive( CBaseFilterImpl
* pImpl
)
622 CAsyncSourceImpl_THIS(pImpl
,basefilter
);
624 TRACE( "(%p)\n", This
);
626 CAsyncReaderImpl_EndThread(&This
->pPin
->async
);
631 static const CBaseFilterHandlers filterhandlers
=
633 CAsyncSourceImpl_OnActive
, /* pOnActive */
634 CAsyncSourceImpl_OnInactive
, /* pOnInactive */
638 /***************************************************************************
640 * new/delete CAsyncSourceImpl
644 /* can I use offsetof safely? - FIXME? */
645 static QUARTZ_IFEntry FilterIFEntries
[] =
647 { &IID_IPersist
, offsetof(CAsyncSourceImpl
,basefilter
)-offsetof(CAsyncSourceImpl
,unk
) },
648 { &IID_IMediaFilter
, offsetof(CAsyncSourceImpl
,basefilter
)-offsetof(CAsyncSourceImpl
,unk
) },
649 { &IID_IBaseFilter
, offsetof(CAsyncSourceImpl
,basefilter
)-offsetof(CAsyncSourceImpl
,unk
) },
650 { &IID_IFileSourceFilter
, offsetof(CAsyncSourceImpl
,filesrc
)-offsetof(CAsyncSourceImpl
,unk
) },
653 static void QUARTZ_DestroyAsyncSource(IUnknown
* punk
)
655 CAsyncSourceImpl_THIS(punk
,unk
);
657 TRACE( "(%p)\n", This
);
659 if ( This
->pPin
!= NULL
)
661 IUnknown_Release(This
->pPin
->unk
.punkControl
);
665 This
->m_pHandler
->pCleanup( This
);
667 CFileSourceFilterImpl_UninitIFileSourceFilter(&This
->filesrc
);
668 CBaseFilterImpl_UninitIBaseFilter(&This
->basefilter
);
670 DeleteCriticalSection( &This
->csFilter
);
673 HRESULT
QUARTZ_CreateAsyncSource(
674 IUnknown
* punkOuter
,void** ppobj
,
675 const CLSID
* pclsidAsyncSource
,
676 LPCWSTR pwszAsyncSourceName
,
677 LPCWSTR pwszOutPinName
,
678 const AsyncSourceHandlers
* pHandler
)
680 CAsyncSourceImpl
* This
= NULL
;
683 TRACE("(%p,%p)\n",punkOuter
,ppobj
);
685 This
= (CAsyncSourceImpl
*)
686 QUARTZ_AllocObj( sizeof(CAsyncSourceImpl
) );
688 return E_OUTOFMEMORY
;
691 This
->m_pHandler
= pHandler
;
692 This
->m_pUserData
= NULL
;
694 QUARTZ_IUnkInit( &This
->unk
, punkOuter
);
696 hr
= CBaseFilterImpl_InitIBaseFilter(
698 This
->unk
.punkControl
,
704 /* construct this class. */
705 hr
= CFileSourceFilterImpl_InitIFileSourceFilter(
706 &This
->filesrc
, This
->unk
.punkControl
,
707 This
, &This
->csFilter
);
710 CBaseFilterImpl_UninitIBaseFilter(&This
->basefilter
);
716 QUARTZ_FreeObj(This
);
720 This
->unk
.pEntries
= FilterIFEntries
;
721 This
->unk
.dwEntries
= sizeof(FilterIFEntries
)/sizeof(FilterIFEntries
[0]);
722 This
->unk
.pOnFinalRelease
= QUARTZ_DestroyAsyncSource
;
723 InitializeCriticalSection( &This
->csFilter
);
725 /* create the output pin. */
730 IUnknown_Release( This
->unk
.punkControl
);
734 *ppobj
= (void*)&(This
->unk
);
739 /***************************************************************************
741 * new/delete CAsyncSourcePinImpl
745 /* can I use offsetof safely? - FIXME? */
746 static QUARTZ_IFEntry OutPinIFEntries
[] =
748 { &IID_IPin
, offsetof(CAsyncSourcePinImpl
,pin
)-offsetof(CAsyncSourcePinImpl
,unk
) },
749 /***{ &IID_IAsyncReader, offsetof(CAsyncSourcePinImpl,async)-offsetof(CAsyncSourcePinImpl,unk) },***/
752 static HRESULT
CAsyncSourceImpl_OnQueryInterface(
753 IUnknown
* punk
, const IID
* piid
, void** ppobj
)
755 CAsyncSourcePinImpl_THIS(punk
,unk
);
757 if ( IsEqualGUID( &IID_IAsyncReader
, piid
) )
759 *ppobj
= (void*)&This
->async
;
760 IUnknown_AddRef(punk
);
761 This
->bAsyncReaderQueried
= TRUE
;
765 return E_NOINTERFACE
;
768 static void QUARTZ_DestroyAsyncSourcePin(IUnknown
* punk
)
770 CAsyncSourcePinImpl_THIS(punk
,unk
);
772 TRACE( "(%p)\n", This
);
774 CAsyncReaderImpl_UninitIAsyncReader( &This
->async
);
775 CPinBaseImpl_UninitIPin( &This
->pin
);
778 HRESULT
QUARTZ_CreateAsyncSourcePin(
779 CAsyncSourceImpl
* pFilter
,
780 CRITICAL_SECTION
* pcsPin
,
781 CAsyncSourcePinImpl
** ppPin
,
782 LPCWSTR pwszPinName
)
784 CAsyncSourcePinImpl
* This
= NULL
;
787 TRACE("(%p,%p,%p)\n",pFilter
,pcsPin
,ppPin
);
789 This
= (CAsyncSourcePinImpl
*)
790 QUARTZ_AllocObj( sizeof(CAsyncSourcePinImpl
) );
792 return E_OUTOFMEMORY
;
794 QUARTZ_IUnkInit( &This
->unk
, NULL
);
795 This
->qiext
.pNext
= NULL
;
796 This
->qiext
.pOnQueryInterface
= &CAsyncSourceImpl_OnQueryInterface
;
797 QUARTZ_IUnkAddDelegation( &This
->unk
, &This
->qiext
);
799 This
->bAsyncReaderQueried
= FALSE
;
800 This
->pSource
= pFilter
;
802 hr
= CPinBaseImpl_InitIPin(
804 This
->unk
.punkControl
,
806 &pFilter
->basefilter
,
809 &outputpinhandlers
);
813 hr
= CAsyncReaderImpl_InitIAsyncReader(
815 This
->unk
.punkControl
,
820 CPinBaseImpl_UninitIPin( &This
->pin
);
826 QUARTZ_FreeObj(This
);
830 This
->unk
.pEntries
= OutPinIFEntries
;
831 This
->unk
.dwEntries
= sizeof(OutPinIFEntries
)/sizeof(OutPinIFEntries
[0]);
832 This
->unk
.pOnFinalRelease
= QUARTZ_DestroyAsyncSourcePin
;
836 TRACE("returned successfully.\n");