2 * Modified for use with MPlayer, detailed changelog at
3 * http://svn.mplayerhq.hu/mplayer/trunk/
6 #include "loader/wine/winerror.h"
7 #include "loader/wine/windef.h"
14 static inline int output_unimplemented(const char* s
, void* p
)
16 Debug
printf("%s(%p) called (UNIMPLEMENTED)", s
, p
);
21 An object beyond interface IEnumMediaTypes.
22 Returned by COutputPin through call IPin::EnumMediaTypes().
24 typedef struct CEnumMediaTypes
26 IEnumMediaTypes_vt
* vt
;
33 IMemOutput interface implementation
40 long* frame_size_pointer
;
41 MemAllocator
* pAllocator
;
46 * \brief IEnumMediaTypes:Next (retrives a specified number of media types )
48 * \param[in] This pointer to CEnumMediaTypes object
49 * \param[in] cMediaTypes number of media types to retrive
50 * \param[out] ppMediaTypes array of AM_MEDIA_TYPE structure pointers of size cMediaTypes
51 * \param[out] pcFetched address of variables that receives number of returned media types
53 * \return S_OK - success
54 * \return S_FALSE - did not return as meny structures as requested
55 * \return E_INVALIDARG Invalid argument
56 * \return E_POINTER Null pointer
57 * \return VFW_E_ENUM_OUT_OF_SYNC - pin's state has changed and is now inconsistent with enumerator
60 static HRESULT STDCALL
CEnumMediaTypes_Next(IEnumMediaTypes
* This
,
61 /* [in] */ ULONG cMediaTypes
,
62 /* [size_is][out] */ AM_MEDIA_TYPE
**ppMediaTypes
,
63 /* [out] */ ULONG
*pcFetched
)
65 AM_MEDIA_TYPE
* type
= &((CEnumMediaTypes
*)This
)->type
;
66 Debug
printf("CEnumMediaTypes::Next(%p) called\n", This
);
69 if (!pcFetched
&& (cMediaTypes
!=1))
76 ppMediaTypes
[0] = CreateMediaType(type
);
83 /* I expect that these methods are unused. */
86 * \brief IEnumMediaTypes::Skip (skips over a specified number of media types)
88 * \param[in] This pointer to CEnumMEdiaTypes object
89 * \param[in] cMediaTypes number of media types to skip
91 * \return S_OK - success
92 * \return S_FALSE - skipped past the end of the sequence
93 * \return VFW_E_ENUM_OUT_OF_SYNC - pin's state has changed and is now inconsistent with enumerator
96 static HRESULT STDCALL
CEnumMediaTypes_Skip(IEnumMediaTypes
* This
,
97 /* [in] */ ULONG cMediaTypes
)
99 return output_unimplemented("CEnumMediaTypes::Skip", This
);
103 * \brief IEnumMediaTypes::Reset (resets enumeration sequence to beginning)
105 * \param[in] This pointer to CEnumMEdiaTypes object
107 * \return S_OK - success
110 static HRESULT STDCALL
CEnumMediaTypes_Reset(IEnumMediaTypes
* This
)
112 Debug
printf("CEnumMediaTypes::Reset(%p) called\n", This
);
117 * \brief IEnumMediaTypes::Clone (makes a copy of enumerator, returned object
118 * starts at the same position as original)
120 * \param[in] This pointer to CEnumMEdiaTypes object
121 * \param[out] ppEnum address of variable that receives pointer to IEnumMediaTypes interface
123 * \return S_OK - success
124 * \return E_OUTOFMEMRY - Insufficient memory
125 * \return E_POINTER - Null pointer
126 * \return VFW_E_ENUM_OUT_OF_SYNC - pin's state has changed and is now inconsistent with enumerator
129 static HRESULT STDCALL
CEnumMediaTypes_Clone(IEnumMediaTypes
* This
,
130 /* [out] */ IEnumMediaTypes
**ppEnum
)
132 Debug
printf("CEnumMediaTypes::Clone(%p) called\n", This
);
137 * \brief CEnumMediaTypes destructor
139 * \param[in] This pointer to CEnumMediaTypes object
142 static void CEnumMediaTypes_Destroy(CEnumMediaTypes
* This
)
144 FreeMediaType(&(This
->type
));
149 // IEnumMediaTypes->IUnknown methods
150 IMPLEMENT_IUNKNOWN(CEnumMediaTypes
)
153 * \brief CEnumMediaTypes constructor
155 * \param[in] amt media type for enumerating
157 * \return pointer to CEnumMEdiaTypes object or NULL if error occured
160 static CEnumMediaTypes
* CEnumMediaTypesCreate(const AM_MEDIA_TYPE
* amt
)
162 CEnumMediaTypes
*This
= malloc(sizeof(CEnumMediaTypes
)) ;
167 This
->vt
= malloc(sizeof(IEnumMediaTypes_vt
));
175 CopyMediaType(&(This
->type
),amt
);
177 This
->vt
->QueryInterface
= CEnumMediaTypes_QueryInterface
;
178 This
->vt
->AddRef
= CEnumMediaTypes_AddRef
;
179 This
->vt
->Release
= CEnumMediaTypes_Release
;
180 This
->vt
->Next
= CEnumMediaTypes_Next
;
181 This
->vt
->Skip
= CEnumMediaTypes_Skip
;
182 This
->vt
->Reset
= CEnumMediaTypes_Reset
;
183 This
->vt
->Clone
= CEnumMediaTypes_Clone
;
185 This
->interfaces
[0] = IID_IUnknown
;
186 This
->interfaces
[1] = IID_IEnumMediaTypes
;
196 * This is implementation of INPUT pin in DirectShow's terms
203 * \brief IUnknown::QueryInterface (query object for interface)
204 * \param[in] This pointer to IUnknown interface
205 * \param[in] iid GUID of requested interface
206 * \param[out] ppv receives pointer to interface
208 * \return S_OK - success (and *ppv contains valid pointer)
209 * \return E_NOINTERFACE - interface not found (and *ppv was set NULL)
212 * Make sure to call Release on received interface when you are done
215 static HRESULT STDCALL
COutputPin_QueryInterface(IUnknown
* This
, const GUID
* iid
, void** ppv
)
217 COutputPin
* p
= (COutputPin
*) This
;
219 Debug
printf("COutputPin_QueryInterface(%p) called\n", This
);
223 if (memcmp(iid
, &IID_IUnknown
, 16) == 0)
229 if (memcmp(iid
, &IID_IMemInputPin
, 16) == 0)
232 p
->mempin
->vt
->AddRef((IUnknown
*)*ppv
);
236 Debug
printf("Unknown interface : %08x-%04x-%04x-%02x%02x-"
237 "%02x%02x%02x%02x%02x%02x\n",
238 iid
->f1
, iid
->f2
, iid
->f3
,
239 (unsigned char)iid
->f4
[1], (unsigned char)iid
->f4
[0],
240 (unsigned char)iid
->f4
[2], (unsigned char)iid
->f4
[3],
241 (unsigned char)iid
->f4
[4], (unsigned char)iid
->f4
[5],
242 (unsigned char)iid
->f4
[6], (unsigned char)iid
->f4
[7]);
243 return E_NOINTERFACE
;
249 * \brief IPin::Connect (connects pin to another pin)
251 * \param[in] This pointer to IPin interface
252 * \param[in] pReceivePin pointer to IPin interface of remote pin
253 * \param[in] pmt suggested media type for link. Can be NULL (any media type)
255 * \return S_OK - success.
256 * \return VFW_E_ALREADY_CONNECTED - pin already connected
257 * \return VFW_E_NOT_STOPPED - filter is active
258 * \return VFW_E_TYPE_NOT_ACCEPT - type is not acceptable
259 * \return Apropriate error code otherwise.
262 static HRESULT STDCALL
COutputPin_Connect(IPin
* This
,
263 /* [in] */ IPin
*pReceivePin
,
264 /* [in] */ /* const */ AM_MEDIA_TYPE
*pmt
)
266 Debug
printf("COutputPin_Connect(%p) called\n",This
);
268 *pmt=((COutputPin*)This)->type;
271 pmt->pbFormat=malloc(pmt->cbFormat);
272 memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat);
276 return 0;// XXXXXXXXXXXXX CHECKME XXXXXXXXXXXXXXX
277 // if I put return 0; here, it crashes
281 * \brief IPin::ReceiveConnection (accepts a connection from another pin)
283 * \param[in] This pointer to IPin interface
284 * \param[in] pConnector connecting pin's IPin interface
285 * \param[in] pmt suggested media type for connection
287 * \return S_OK - success
288 * \return E_POINTER - Null pointer
289 * \return VFW_E_ALREADY_CONNECTED - pin already connected
290 * \return VFW_E_NOT_STOPPED - filter is active
291 * \return VFW_E_TYPE_NOT_ACCEPT - type is not acceptable
294 * When returning S_OK method should also do the following:
295 * - store media type and return the same type in IPin::ConnectionMediaType
296 * - store pConnector and return it in IPin::ConnectedTo
299 static HRESULT STDCALL
COutputPin_ReceiveConnection(IPin
* This
,
300 /* [in] */ IPin
*pConnector
,
301 /* [in] */ const AM_MEDIA_TYPE
*pmt
)
303 Debug
printf("COutputPin_ReceiveConnection(%p) called\n", This
);
304 ((COutputPin
*)This
)->remote
= pConnector
;
309 * \brief IPin::Disconnect (accepts a connection from another pin)
311 * \param[in] This pointer to IPin interface
313 * \return S_OK - success
314 * \return S_FALSE - pin was not connected
315 * \return VFW_E_NOT_STOPPED - filter is active
318 * To break connection you have to also call Disconnect on other pin
320 static HRESULT STDCALL
COutputPin_Disconnect(IPin
* This
)
322 Debug
printf("COutputPin_Disconnect(%p) called\n", This
);
327 * \brief IPin::ConnectedTo (retrieves pointer to the connected pin, if such exist)
329 * \param[in] This pointer to IPin interface
330 * \param[out] pPin pointer to remote pin's IPin interface
332 * \return S_OK - success
333 * \return E_POINTER - Null pointer
334 * \return VFW_E_NOT_CONNECTED - pin is not connected
337 * Caller must call Release on received IPin, when done
339 static HRESULT STDCALL
COutputPin_ConnectedTo(IPin
* This
,
340 /* [out] */ IPin
**pPin
)
342 Debug
printf("COutputPin_ConnectedTo(%p) called\n", This
);
345 *pPin
= ((COutputPin
*)This
)->remote
;
350 * \brief IPin::ConnectionMediaType (retrieves media type for connection, if such exist)
352 * \param[in] This pointer to IPin interface
353 * \param[out] pmt pointer to AM_MEDIA_TYPE, that receives connection media type
355 * \return S_OK - success
356 * \return E_POINTER - Null pointer
357 * \return VFW_E_NOT_CONNECTED - pin is not connected
360 static HRESULT STDCALL
COutputPin_ConnectionMediaType(IPin
* This
,
361 /* [out] */ AM_MEDIA_TYPE
*pmt
)
363 Debug
printf("COutputPin_ConnectionMediaType(%p) called\n",This
);
366 CopyMediaType(pmt
,&(((COutputPin
*)This
)->type
));
371 * \brief IPin::QueryPinInfo (retrieves information about the pin)
373 * \param[in] This pointer to IPin interface
374 * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info
376 * \return S_OK - success
377 * \return E_POINTER - Null pointer
380 * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done
383 static HRESULT STDCALL
COutputPin_QueryPinInfo(IPin
* This
,
384 /* [out] */ PIN_INFO
*pInfo
)
386 return output_unimplemented("COutputPin_QueryPinInfo", This
);
390 * \brief IPin::QueryDirection (retrieves pin direction)
392 * \param[in] This pointer to IPin interface
393 * \param[out] pPinDir pointer to variable, that receives pin direction (PINDIR_INPUT,PINDIR_OUTPUT)
395 * \return S_OK - success
396 * \return E_POINTER - Null pointer
399 static HRESULT STDCALL
COutputPin_QueryDirection(IPin
* This
,
400 /* [out] */ PIN_DIRECTION
*pPinDir
)
402 Debug
printf("COutputPin_QueryDirection(%p) called\n", This
);
405 *pPinDir
= PINDIR_INPUT
;
410 * \brief IPin::QueryId (retrieves pin identificator)
412 * \param[in] This pointer to IPin interface
413 * \param[out] Id adress of variable, that receives string with pin's Id.
415 * \return S_OK - success
416 * \return E_OUTOFMEMORY - Insufficient memory
417 * \return E_POINTER - Null pointer
420 * Pin's Id is not the same as pin's name
423 static HRESULT STDCALL
COutputPin_QueryId(IPin
* This
,
424 /* [out] */ LPWSTR
*Id
)
426 return output_unimplemented("COutputPin_QueryId", This
);
430 * \brief IPin::QueryAccept (determines can media type be accepted or not)
432 * \param[in] This pointer to IPin interface
433 * \param[in] pmt Media type to check
435 * \return S_OK - success
436 * \return S_FALSE - pin rejects media type
439 static HRESULT STDCALL
COutputPin_QueryAccept(IPin
* This
,
440 /* [in] */ const AM_MEDIA_TYPE
*pmt
)
442 return output_unimplemented("COutputPin_QueryAccept", This
);
446 * \brief IPin::EnumMediaTypes (enumerates the pin's preferred media types)
448 * \param[in] This pointer to IPin interface
449 * \param[out] ppEnum adress of variable that receives pointer to IEnumMEdiaTypes interface
451 * \return S_OK - success
452 * \return E_OUTOFMEMORY - Insufficient memory
453 * \return E_POINTER - Null pointer
456 * Caller must call Release on received interface when done
459 static HRESULT STDCALL
COutputPin_EnumMediaTypes(IPin
* This
,
460 /* [out] */ IEnumMediaTypes
**ppEnum
)
462 Debug
printf("COutputPin_EnumMediaTypes(%p) called\n",This
);
465 *ppEnum
= (IEnumMediaTypes
*) CEnumMediaTypesCreate(&((COutputPin
*)This
)->type
);
470 * \brief IPin::QueryInternalConnections (retries pin's internal connections)
472 * \param[in] This pointer to IPin interface
473 * \param[out] apPin Array that receives pins, internally connected to this
474 * \param[in,out] nPint Size of an array
476 * \return S_OK - success
477 * \return S_FALSE - pin rejects media type
478 * \return E_NOTIMPL - not implemented
481 static HRESULT STDCALL
COutputPin_QueryInternalConnections(IPin
* This
,
482 /* [out] */ IPin
**apPin
,
483 /* [out][in] */ ULONG
*nPin
)
485 return output_unimplemented("COutputPin_QueryInternalConnections", This
);
489 * \brief IPin::EndOfStream (notifies pin, that no data is expected, until new run command)
491 * \param[in] This pointer to IPin interface
493 * \return S_OK - success
494 * \return E_UNEXPECTED - The pin is output pin
497 * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream,
498 * IMemAllocator::GetBuffer runs in different (streaming) thread then other
499 * methods (application thread).
500 * IMemoryInputPin::NewSegment runs either in streaming or application thread.
501 * Developer must use critical sections for thread-safing work.
504 static HRESULT STDCALL
COutputPin_EndOfStream(IPin
* This
)
506 return output_unimplemented("COutputPin_EndOfStream", This
);
510 * \brief IPin::BeginFlush (begins a flush operation)
512 * \param[in] This pointer to IPin interface
514 * \return S_OK - success
515 * \return E_UNEXPECTED - The pin is output pin
518 static HRESULT STDCALL
COutputPin_BeginFlush(IPin
* This
)
520 return output_unimplemented("COutputPin_BeginFlush", This
);
524 * \brief IPin::EndFlush (ends a flush operation)
526 * \param[in] This pointer to IPin interface
528 * \return S_OK - success
529 * \return E_UNEXPECTED - The pin is output pin
532 static HRESULT STDCALL
COutputPin_EndFlush(IPin
* This
)
534 return output_unimplemented("COutputPin_EndFlush", This
);
538 * \brief IPin::NewSegment (media sample received after this call grouped as segment with common
539 * start,stop time and rate)
541 * \param[in] This pointer to IPin interface
542 * \param[in] tStart start time of new segment
543 * \param[in] tStop end time of new segment
544 * \param[in] dRate rate at wich segment should be processed
546 * \return S_OK - success
547 * \return E_UNEXPECTED - The pin is output pin
550 static HRESULT STDCALL
COutputPin_NewSegment(IPin
* This
,
551 /* [in] */ REFERENCE_TIME tStart
,
552 /* [in] */ REFERENCE_TIME tStop
,
553 /* [in] */ double dRate
)
555 Debug
printf("COutputPin_NewSegment(%Ld,%Ld,%f) called\n",
556 tStart
, tStop
, dRate
);
562 // IMemInputPin->IUnknown methods
565 * \brief IUnknown::QueryInterface (query object for interface)
567 * \param[in] This pointer to IUnknown interface
568 * \param[in] iid GUID of requested interface
569 * \param[out] ppv receives pointer to interface
571 * \return S_OK - success (and *ppv contains valid pointer)
572 * \return E_NOINTERFACE - interface not found (and *ppv was set NULL)
575 * Make sure to call Release on received interface when you are done
578 static HRESULT STDCALL
COutputMemPin_QueryInterface(IUnknown
* This
, const GUID
* iid
, void** ppv
)
580 COutputMemPin
* p
= (COutputMemPin
*)This
;
582 Debug
printf("COutputMemPin_QueryInterface(%p) called\n", This
);
586 if(!memcmp(iid
, &IID_IUnknown
, 16))
592 /*if(!memcmp(iid, &IID_IPin, 16))
594 COutputPin* ptr=(COutputPin*)(This-1);
596 AddRef((IUnknown*)ptr);
599 if(!memcmp(iid
, &IID_IMemInputPin
, 16))
605 Debug
printf("Unknown interface : %08x-%04x-%04x-%02x%02x-" \
606 "%02x%02x%02x%02x%02x%02x\n",
607 iid
->f1
, iid
->f2
, iid
->f3
,
608 (unsigned char)iid
->f4
[1], (unsigned char)iid
->f4
[0],
609 (unsigned char)iid
->f4
[2], (unsigned char)iid
->f4
[3],
610 (unsigned char)iid
->f4
[4], (unsigned char)iid
->f4
[5],
611 (unsigned char)iid
->f4
[6], (unsigned char)iid
->f4
[7]);
612 return E_NOINTERFACE
;
615 // IMemInputPin methods
618 * \brief IMemInputPin::GetAllocator (retrives memory allocator, proposed by pin)
620 * \param[in] This pointer to IMemInputPin interface
621 * \param[out] ppAllocator address of variable that receives allocator's IMemAllocator interface
623 * \return S_OK - success
624 * \return VFW_E_NO_ALLOCATOR - No allocator
627 * Make sure to call Release on received interface when you are done
630 static HRESULT STDCALL
COutputMemPin_GetAllocator(IMemInputPin
* This
,
631 /* [out] */ IMemAllocator
** ppAllocator
)
633 Debug
printf("COutputMemPin_GetAllocator(%p, %p) called\n", This
->vt
, ppAllocator
);
634 *ppAllocator
= (IMemAllocator
*) MemAllocatorCreate();
640 * \brief IMemInputPin::NotifyAllocator (specifies an allocator for the connection)
642 * \param[in] This pointer to IMemInputPin interface
643 * \param[in] pAllocator allocator's IMemAllocator interface
644 * \param[in] bReadOnly specifies whether samples from allocator are readonly
646 * \return S_OK - success
647 * \return Apropriate error code otherwise
650 static HRESULT STDCALL
COutputMemPin_NotifyAllocator(IMemInputPin
* This
,
651 /* [in] */ IMemAllocator
* pAllocator
,
652 /* [in] */ int bReadOnly
)
654 Debug
printf("COutputMemPin_NotifyAllocator(%p, %p) called\n", This
, pAllocator
);
655 ((COutputMemPin
*)This
)->pAllocator
= (MemAllocator
*) pAllocator
;
660 * \brief IMemInputPin::GetAllocatorRequirements (retrieves allocator properties requested by
663 * \param[in] This pointer to IMemInputPin interface
664 * \param[out] pProps pointer to a structure that receives allocator properties
666 * \return S_OK - success
667 * \return E_NOTIMPL - Not implemented
668 * \return E_POINTER - Null pointer
671 static HRESULT STDCALL
COutputMemPin_GetAllocatorRequirements(IMemInputPin
* This
,
672 /* [out] */ ALLOCATOR_PROPERTIES
* pProps
)
674 return output_unimplemented("COutputMemPin_GetAllocatorRequirements", This
);
678 * \brief IMemInputPin::Receive (receives the next media sample int thre stream)
680 * \param[in] This pointer to IMemInputPin interface
681 * \param[in] pSample pointer to sample's IMediaSample interface
683 * \return S_OK - success
684 * \return S_FALSE - The sample was rejected
685 * \return E_POINTER - Null pointer
686 * \return VFW_E_INVALIDMEDIATYPE - invalid media type
687 * \return VFW_E_RUNTIME_ERROR - run-time error occured
688 * \return VFW_E_WRONG_STATE - pin is stopped
691 * Method san do on of the following:
693 * - accept sample and process it in another thread
694 * - accept sample and process it before returning
696 * In second case method should increase reference count for sample (through AddRef)
697 * In the last case method might block indefinitely. If this might
698 * happen IMemInpuPin::ReceiveCAnBlock returns S_OK
701 * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream,
702 * IMemAllocator::GetBuffer runs in different (streaming) thread then other
703 * methods (application thread).
704 * IMemoryInputPin::NewSegment runs either in streaming or application thread.
705 * Developer must use critical sections for thread-safing work.
708 static HRESULT STDCALL
COutputMemPin_Receive(IMemInputPin
* This
,
709 /* [in] */ IMediaSample
* pSample
)
711 Debug
printf("COutputMemPin_Receive(%p) called\n", This
);
715 if(((COutputMemPin
*)This
)->parent
->SampleProc
)
716 return ((COutputMemPin
*)This
)->parent
->SampleProc(((COutputMemPin
*)This
)->parent
->pUserData
,pSample
);
722 * \brief IMemInputPin::ReceiveMultiple (receives multiple samples in the stream)
724 * \param[in] This pointer to IMemInputPin interface
725 * \param[in] pSamples pointer to array with samples
726 * \param[in] nSamples number of samples in array
727 * \param[out] nSamplesProcessed number of processed samples
729 * \return S_OK - success
730 * \return S_FALSE - The sample was rejected
731 * \return E_POINTER - Null pointer
732 * \return VFW_E_INVALIDMEDIATYPE - invalid media type
733 * \return VFW_E_RUNTIME_ERROR - run-time error occured
734 * \return VFW_E_WRONG_STATE - pin is stopped
737 * This method behaves like IMemInputPin::Receive but for array of samples
740 * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream,
741 * IMemAllocator::GetBuffer runs in different (streaming) thread then other
742 * methods (application thread).
743 * IMemoryInputPin::NewSegment runs either in streaming or application thread.
744 * Developer must use critical sections for thread-safing work.
747 static HRESULT STDCALL
COutputMemPin_ReceiveMultiple(IMemInputPin
* This
,
748 /* [size_is][in] */ IMediaSample
**pSamples
,
749 /* [in] */ long nSamples
,
750 /* [out] */ long *nSamplesProcessed
)
753 Debug
printf("COutputMemPin_ReceiveMultiple(%p) %ld\n", This
,nSamples
);
754 for(*nSamplesProcessed
=0; *nSamplesProcessed
< nSamples
; *nSamplesProcessed
++) {
755 hr
= This
->vt
->Receive(This
,pSamples
[*nSamplesProcessed
]);
756 if (hr
!= S_OK
) break;
762 * \brief IMemInputPin::ReceiveCanBlock (determines whether IMemInputPin:::Receive might block)
764 * \param[in] This pointer to IMemInputPin interface
766 * \return S_OK - the pin might block
767 * \return S_FALSE - the pin will not block
770 static HRESULT STDCALL
COutputMemPin_ReceiveCanBlock(IMemInputPin
* This
)
772 return output_unimplemented("COutputMemPin_ReceiveCanBlock", This
);
776 * \brief COutputPin::SetNewFormat(sets new media format for the pin)
778 * \param[in] This pointer to COutputPin class
779 * \param[in] amt new media format
782 static void COutputPin_SetNewFormat(COutputPin
* This
, const AM_MEDIA_TYPE
* amt
)
784 CopyMediaType(&(This
->type
),amt
);
788 * \brief COutputPin destructor
790 * \param[in] This pointer to COutputPin class
793 static void COutputPin_Destroy(COutputPin
* This
)
795 free(This
->mempin
->vt
);
798 FreeMediaType(&(This
->type
));
803 * \brief IUnknown::AddRef (increases reference counter for interface)
805 * \param[in] This pointer to IUnknown class
807 * \return new value of reference counter
810 * Return value should be used only for debug purposes
813 static HRESULT STDCALL
COutputPin_AddRef(IUnknown
* This
)
815 Debug
printf("COutputPin_AddRef(%p) called (%d)\n", This
, ((COutputPin
*)This
)->refcount
);
816 ((COutputPin
*)This
)->refcount
++;
821 * \brief IUnknown::Release (desreases reference counter for interface)
823 * \param[in] This pointer to IUnknown class
825 * \return new value of reference counter
828 * When reference counter reaches zero calls destructor
829 * Return value should be used only for debug purposes
832 static HRESULT STDCALL
COutputPin_Release(IUnknown
* This
)
834 Debug
printf("COutputPin_Release(%p) called (%d)\n", This
, ((COutputPin
*)This
)->refcount
);
835 if (--((COutputPin
*)This
)->refcount
<= 0)
836 COutputPin_Destroy((COutputPin
*)This
);
842 * \brief IUnknown::AddRef (increases reference counter for interface)
844 * \param[in] This pointer to IUnknown class
846 * \return new value of reference counter
849 * Return value should be used only for debug purposes
852 static HRESULT STDCALL
COutputMemPin_AddRef(IUnknown
* This
)
854 COutputMemPin
* p
= (COutputMemPin
*) This
;
855 Debug
printf("COutputMemPin_AddRef(%p) called (%p, %d)\n", p
, p
->parent
, p
->parent
->refcount
);
856 p
->parent
->refcount
++;
861 * \brief IUnknown::Release (desreases reference counter for interface)
863 * \param[in] This pointer to IUnknown class
865 * \return new value of reference counter
868 * When reference counter reaches zero calls destructor
869 * Return value should be used only for debug purposes
872 static HRESULT STDCALL
COutputMemPin_Release(IUnknown
* This
)
874 COutputMemPin
* p
= (COutputMemPin
*) This
;
875 Debug
printf("COutputMemPin_Release(%p) called (%p, %d)\n",
876 p
, p
->parent
, p
->parent
->refcount
);
877 if (--p
->parent
->refcount
<= 0)
878 COutputPin_Destroy(p
->parent
);
883 * \brief COutputPin constructor
885 * \param[in] amt media type for pin
887 * \return pointer to COutputPin if success
888 * \return NULL if error occured
891 COutputPin
* COutputPinCreate(const AM_MEDIA_TYPE
* amt
,SAMPLEPROC SampleProc
,void* pUserData
)
893 COutputPin
* This
= malloc(sizeof(COutputPin
));
894 IMemInputPin_vt
* ivt
;
899 This
->vt
= malloc(sizeof(IPin_vt
));
900 This
->mempin
= malloc(sizeof(COutputMemPin
));
901 ivt
= malloc(sizeof(IMemInputPin_vt
));
903 if (!This
->vt
|| !This
->mempin
|| !ivt
)
905 COutputPin_Destroy(This
);
910 This
->SampleProc
=SampleProc
;
911 This
->pUserData
=pUserData
;
913 This
->mempin
->vt
= ivt
;
917 CopyMediaType(&(This
->type
),amt
);
919 This
->vt
->QueryInterface
= COutputPin_QueryInterface
;
920 This
->vt
->AddRef
= COutputPin_AddRef
;
921 This
->vt
->Release
= COutputPin_Release
;
922 This
->vt
->Connect
= COutputPin_Connect
;
923 This
->vt
->ReceiveConnection
= COutputPin_ReceiveConnection
;
924 This
->vt
->Disconnect
= COutputPin_Disconnect
;
925 This
->vt
->ConnectedTo
= COutputPin_ConnectedTo
;
926 This
->vt
->ConnectionMediaType
= COutputPin_ConnectionMediaType
;
927 This
->vt
->QueryPinInfo
= COutputPin_QueryPinInfo
;
928 This
->vt
->QueryDirection
= COutputPin_QueryDirection
;
929 This
->vt
->QueryId
= COutputPin_QueryId
;
930 This
->vt
->QueryAccept
= COutputPin_QueryAccept
;
931 This
->vt
->EnumMediaTypes
= COutputPin_EnumMediaTypes
;
932 This
->vt
->QueryInternalConnections
= COutputPin_QueryInternalConnections
;
933 This
->vt
->EndOfStream
= COutputPin_EndOfStream
;
934 This
->vt
->BeginFlush
= COutputPin_BeginFlush
;
935 This
->vt
->EndFlush
= COutputPin_EndFlush
;
936 This
->vt
->NewSegment
= COutputPin_NewSegment
;
938 This
->mempin
->vt
->QueryInterface
= COutputMemPin_QueryInterface
;
939 This
->mempin
->vt
->AddRef
= COutputMemPin_AddRef
;
940 This
->mempin
->vt
->Release
= COutputMemPin_Release
;
941 This
->mempin
->vt
->GetAllocator
= COutputMemPin_GetAllocator
;
942 This
->mempin
->vt
->NotifyAllocator
= COutputMemPin_NotifyAllocator
;
943 This
->mempin
->vt
->GetAllocatorRequirements
= COutputMemPin_GetAllocatorRequirements
;
944 This
->mempin
->vt
->Receive
= COutputMemPin_Receive
;
945 This
->mempin
->vt
->ReceiveMultiple
= COutputMemPin_ReceiveMultiple
;
946 This
->mempin
->vt
->ReceiveCanBlock
= COutputMemPin_ReceiveCanBlock
;
948 This
->mempin
->frame_size_pointer
= 0;
949 This
->mempin
->frame_pointer
= 0;
950 This
->mempin
->pAllocator
= 0;
951 This
->mempin
->refcount
= 1;
952 This
->mempin
->parent
= This
;
954 This
->SetNewFormat
= COutputPin_SetNewFormat
;