Started Implementing Video Renderer.
[wine/multimedia.git] / dlls / quartz / asyncsrc.c
bloba5cd0d0d6a14732a795e35d58d8e9f42dfcab189
1 /*
2 * Implements Asynchronous File/URL Source.
4 * FIXME - not work yet.
6 * hidenori@a2.ctktv.ne.jp
7 */
9 #include "config.h"
11 #include "windef.h"
12 #include "winbase.h"
13 #include "wingdi.h"
14 #include "winuser.h"
15 #include "winerror.h"
16 #include "wine/obj_base.h"
17 #include "strmif.h"
18 #include "vfwmsgs.h"
19 #include "uuids.h"
21 #include "debugtools.h"
22 DEFAULT_DEBUG_CHANNEL(quartz);
24 #include "quartz_private.h"
25 #include "asyncsrc.h"
26 #include "memalloc.h"
29 /***************************************************************************
31 * CAsyncReaderImpl internal methods
35 static DWORD WINAPI
36 CAsyncReaderImpl_ThreadEntry( LPVOID pv )
38 CAsyncReaderImpl* This = (CAsyncReaderImpl*)pv;
39 HANDLE hWaitEvents[2];
40 HANDLE hReadEvents[2];
41 DWORD dwRes;
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;
51 while ( 1 )
53 dwRes = WaitForMultipleObjects(2,hWaitEvents,FALSE,INFINITE);
54 if ( dwRes != WAIT_OBJECT_0 )
55 break;
57 /* FIXME - process a queued request */
59 dwRes = WaitForMultipleObjects(2,hReadEvents,FALSE,INFINITE);
60 if ( dwRes != WAIT_OBJECT_0 )
61 break;
64 return 0;
67 static HRESULT
68 CAsyncReaderImpl_BeginThread( CAsyncReaderImpl* This )
70 DWORD dwRes;
71 DWORD dwThreadId;
72 HANDLE hEvents[2];
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 )
80 return E_UNEXPECTED;
82 This->m_hEventInit = CreateEventA(NULL,TRUE,FALSE,NULL);
83 if ( This->m_hEventInit == (HANDLE)NULL )
84 return E_OUTOFMEMORY;
85 This->m_hEventAbort = CreateEventA(NULL,TRUE,FALSE,NULL);
86 if ( This->m_hEventAbort == (HANDLE)NULL )
87 return E_OUTOFMEMORY;
88 This->m_hEventReqQueued = CreateEventA(NULL,TRUE,FALSE,NULL);
89 if ( This->m_hEventReqQueued == (HANDLE)NULL )
90 return E_OUTOFMEMORY;
91 This->m_hEventSampQueued = CreateEventA(NULL,TRUE,FALSE,NULL);
92 if ( This->m_hEventSampQueued == (HANDLE)NULL )
93 return E_OUTOFMEMORY;
94 This->m_hEventCompletion = CreateEventA(NULL,TRUE,FALSE,NULL);
95 if ( This->m_hEventCompletion == (HANDLE)NULL )
96 return E_OUTOFMEMORY;
98 /* create the processing thread. */
99 This->m_hThread = CreateThread(
100 NULL, 0,
101 CAsyncReaderImpl_ThreadEntry,
102 (LPVOID)This,
103 0, &dwThreadId );
104 if ( This->m_hThread == (HANDLE)NULL )
105 return E_FAIL;
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 )
112 return E_FAIL;
114 return NOERROR;
117 static void
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);
171 static ULONG WINAPI
172 CAsyncReaderImpl_fnAddRef(IAsyncReader* iface)
174 ICOM_THIS(CAsyncReaderImpl,iface);
176 TRACE("(%p)->()\n",This);
178 return IUnknown_AddRef(This->punkControl);
181 static ULONG WINAPI
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);
195 HRESULT hr;
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 )
202 return E_POINTER;
204 IMemAllocator_AddRef(pAlloc);
205 hr = IMemAllocator_SetProperties( pAlloc, pProp, &propActual );
206 if ( SUCCEEDED(hr) )
208 *ppAllocActual = pAlloc;
209 return S_OK;
211 IMemAllocator_Release(pAlloc);
213 hr = QUARTZ_CreateMemoryAllocator(NULL,(void**)&punk);
214 if ( FAILED(hr) )
215 return hr;
216 hr = IUnknown_QueryInterface( punk, &IID_IMemAllocator, (void**)&pAlloc );
217 IUnknown_Release(punk);
218 if ( FAILED(hr) )
219 return hr;
221 hr = IMemAllocator_SetProperties( pAlloc, pProp, &propActual );
222 if ( SUCCEEDED(hr) )
224 *ppAllocActual = pAlloc;
225 return S_OK;
227 IMemAllocator_Release(pAlloc);
229 return hr;
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 );
242 return E_NOTIMPL;
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 );
255 return E_NOTIMPL;
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 );
268 return E_NOTIMPL;
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 );
281 return E_NOTIMPL;
284 static HRESULT WINAPI
285 CAsyncReaderImpl_fnLength(IAsyncReader* iface,LONGLONG* pllTotal,LONGLONG* pllAvailable)
287 ICOM_THIS(CAsyncReaderImpl,iface);
288 HRESULT hr;
290 TRACE("(%p)->()\n",This);
292 EnterCriticalSection( This->pcsReader );
293 hr = This->pSource->m_pHandler->pGetLength( This->pSource, pllTotal, pllAvailable );
294 LeaveCriticalSection( This->pcsReader );
296 return hr;
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 );
309 return E_NOTIMPL;
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 );
322 return E_NOTIMPL;
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" );
355 return E_INVALIDARG;
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;
369 return NOERROR;
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);
394 static ULONG WINAPI
395 CFileSourceFilterImpl_fnAddRef(IFileSourceFilter* iface)
397 ICOM_THIS(CFileSourceFilterImpl,iface);
399 TRACE("(%p)->()\n",This);
401 return IUnknown_AddRef(This->punkControl);
404 static ULONG WINAPI
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);
418 HRESULT hr;
420 TRACE("(%p)->(%s,%p)\n",This,debugstr_w(pFileName),pmt);
422 if ( pFileName == NULL )
423 return E_POINTER;
425 if ( This->m_pwszFileName != NULL )
426 return E_UNEXPECTED;
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 );
434 if ( pmt != NULL )
436 hr = QUARTZ_MediaType_Copy( &This->m_mt, pmt );
437 if ( FAILED(hr) )
438 goto err;
440 else
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 );
450 if ( FAILED(hr) )
451 goto err;
453 return NOERROR;
454 err:;
455 return hr;
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 )
467 return E_POINTER;
469 if ( This->m_pwszFileName == NULL )
470 return E_FAIL;
472 hr = QUARTZ_MediaType_Copy( pmt, &This->m_mt );
473 if ( FAILED(hr) )
474 return hr;
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 );
486 return NOERROR;
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" );
511 return E_INVALIDARG;
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) );
522 return NOERROR;
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;
549 return NOERROR;
552 static HRESULT CAsyncSourcePinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPin )
554 CAsyncSourcePinImpl_THIS(pImpl,pin);
556 if ( !This->bAsyncReaderQueried )
557 return E_FAIL;
559 return NOERROR;
562 static HRESULT CAsyncSourcePinImpl_OnDisconnect( CPinBaseImpl* pImpl )
564 CAsyncSourcePinImpl_THIS(pImpl,pin);
566 This->bAsyncReaderQueried = FALSE;
568 return NOERROR;
571 static HRESULT CAsyncSourcePinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
573 CAsyncSourcePinImpl_THIS(pImpl,pin);
575 TRACE("(%p,%p)\n",This,pmt);
576 if ( pmt == NULL )
577 return E_POINTER;
579 if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Stream ) )
580 return E_FAIL;
582 return NOERROR;
585 static const CBasePinHandlers outputpinhandlers =
587 CAsyncSourcePinImpl_OnPreConnect, /* pOnPreConnect */
588 CAsyncSourcePinImpl_OnPostConnect, /* pOnPostConnect */
589 CAsyncSourcePinImpl_OnDisconnect, /* pOnDisconnect */
590 CAsyncSourcePinImpl_CheckMediaType, /* pCheckMediaType */
591 NULL, /* pQualityNotify */
592 NULL, /* pReceive */
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);
609 HRESULT hr;
611 TRACE( "(%p)\n", This );
613 hr = CAsyncReaderImpl_BeginThread(&This->pPin->async);
614 if ( FAILED(hr) )
615 return hr;
617 return NOERROR;
620 static HRESULT CAsyncSourceImpl_OnInactive( CBaseFilterImpl* pImpl )
622 CAsyncSourceImpl_THIS(pImpl,basefilter);
624 TRACE( "(%p)\n", This );
626 CAsyncReaderImpl_EndThread(&This->pPin->async);
628 return NOERROR;
631 static const CBaseFilterHandlers filterhandlers =
633 CAsyncSourceImpl_OnActive, /* pOnActive */
634 CAsyncSourceImpl_OnInactive, /* pOnInactive */
635 NULL, /* pOnStop */
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);
662 This->pPin = NULL;
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;
681 HRESULT hr;
683 TRACE("(%p,%p)\n",punkOuter,ppobj);
685 This = (CAsyncSourceImpl*)
686 QUARTZ_AllocObj( sizeof(CAsyncSourceImpl) );
687 if ( This == NULL )
688 return E_OUTOFMEMORY;
690 This->pPin = NULL;
691 This->m_pHandler = pHandler;
692 This->m_pUserData = NULL;
694 QUARTZ_IUnkInit( &This->unk, punkOuter );
696 hr = CBaseFilterImpl_InitIBaseFilter(
697 &This->basefilter,
698 This->unk.punkControl,
699 pclsidAsyncSource,
700 pwszAsyncSourceName,
701 &filterhandlers );
702 if ( SUCCEEDED(hr) )
704 /* construct this class. */
705 hr = CFileSourceFilterImpl_InitIFileSourceFilter(
706 &This->filesrc, This->unk.punkControl,
707 This, &This->csFilter );
708 if ( FAILED(hr) )
710 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
714 if ( FAILED(hr) )
716 QUARTZ_FreeObj(This);
717 return hr;
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. */
726 hr = S_OK;
728 if ( FAILED(hr) )
730 IUnknown_Release( This->unk.punkControl );
731 return hr;
734 *ppobj = (void*)&(This->unk);
736 return S_OK;
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;
762 return S_OK;
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;
785 HRESULT hr;
787 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
789 This = (CAsyncSourcePinImpl*)
790 QUARTZ_AllocObj( sizeof(CAsyncSourcePinImpl) );
791 if ( This == NULL )
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(
803 &This->pin,
804 This->unk.punkControl,
805 pcsPin,
806 &pFilter->basefilter,
807 pwszPinName,
808 TRUE,
809 &outputpinhandlers );
811 if ( SUCCEEDED(hr) )
813 hr = CAsyncReaderImpl_InitIAsyncReader(
814 &This->async,
815 This->unk.punkControl,
816 pFilter,
817 pcsPin );
818 if ( FAILED(hr) )
820 CPinBaseImpl_UninitIPin( &This->pin );
824 if ( FAILED(hr) )
826 QUARTZ_FreeObj(This);
827 return hr;
830 This->unk.pEntries = OutPinIFEntries;
831 This->unk.dwEntries = sizeof(OutPinIFEntries)/sizeof(OutPinIFEntries[0]);
832 This->unk.pOnFinalRelease = QUARTZ_DestroyAsyncSourcePin;
834 *ppPin = This;
836 TRACE("returned successfully.\n");
838 return S_OK;