diff options
Diffstat (limited to 'loader/dshow/outputpin.c')
-rw-r--r-- | loader/dshow/outputpin.c | 957 |
1 files changed, 0 insertions, 957 deletions
diff --git a/loader/dshow/outputpin.c b/loader/dshow/outputpin.c deleted file mode 100644 index a1baf80116..0000000000 --- a/loader/dshow/outputpin.c +++ /dev/null @@ -1,957 +0,0 @@ -/* - * Modified for use with MPlayer, detailed changelog at - * http://svn.mplayerhq.hu/mplayer/trunk/ - */ - -#include "loader/wine/winerror.h" -#include "loader/wine/windef.h" -#include "outputpin.h" -#include "mediatype.h" -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -static inline int output_unimplemented(const char* s, void* p) -{ - Debug printf("%s(%p) called (UNIMPLEMENTED)", s, p); - return E_NOTIMPL; -} - -/** - An object beyond interface IEnumMediaTypes. - Returned by COutputPin through call IPin::EnumMediaTypes(). -*/ -typedef struct CEnumMediaTypes -{ - IEnumMediaTypes_vt* vt; - DECLARE_IUNKNOWN(); - AM_MEDIA_TYPE type; - GUID interfaces[2]; -} CEnumMediaTypes; - -/** - IMemOutput interface implementation -*/ -struct COutputMemPin -{ - IMemInputPin_vt* vt; - DECLARE_IUNKNOWN(); - char** frame_pointer; - long* frame_size_pointer; - MemAllocator* pAllocator; - COutputPin* parent; -}; - -/** - * \brief IEnumMediaTypes:Next (retrives a specified number of media types ) - * - * \param[in] This pointer to CEnumMediaTypes object - * \param[in] cMediaTypes number of media types to retrive - * \param[out] ppMediaTypes array of AM_MEDIA_TYPE structure pointers of size cMediaTypes - * \param[out] pcFetched address of variables that receives number of returned media types - * - * \return S_OK - success - * \return S_FALSE - did not return as meny structures as requested - * \return E_INVALIDARG Invalid argument - * \return E_POINTER Null pointer - * \return VFW_E_ENUM_OUT_OF_SYNC - pin's state has changed and is now inconsistent with enumerator - * - */ -static HRESULT STDCALL CEnumMediaTypes_Next(IEnumMediaTypes * This, - /* [in] */ ULONG cMediaTypes, - /* [size_is][out] */ AM_MEDIA_TYPE **ppMediaTypes, - /* [out] */ ULONG *pcFetched) -{ - AM_MEDIA_TYPE* type = &((CEnumMediaTypes*)This)->type; - Debug printf("CEnumMediaTypes::Next(%p) called\n", This); - if (!ppMediaTypes) - return E_INVALIDARG; - if (!pcFetched && (cMediaTypes!=1)) - return E_INVALIDARG; - if (cMediaTypes <= 0) - return 0; - - if (pcFetched) - *pcFetched=1; - ppMediaTypes[0] = CreateMediaType(type); - - if (cMediaTypes == 1) - return 0; - return 1; -} - -/* I expect that these methods are unused. */ - -/** - * \brief IEnumMediaTypes::Skip (skips over a specified number of media types) - * - * \param[in] This pointer to CEnumMEdiaTypes object - * \param[in] cMediaTypes number of media types to skip - * - * \return S_OK - success - * \return S_FALSE - skipped past the end of the sequence - * \return VFW_E_ENUM_OUT_OF_SYNC - pin's state has changed and is now inconsistent with enumerator - * - */ -static HRESULT STDCALL CEnumMediaTypes_Skip(IEnumMediaTypes * This, - /* [in] */ ULONG cMediaTypes) -{ - return output_unimplemented("CEnumMediaTypes::Skip", This); -} - -/** - * \brief IEnumMediaTypes::Reset (resets enumeration sequence to beginning) - * - * \param[in] This pointer to CEnumMEdiaTypes object - * - * \return S_OK - success - * - */ -static HRESULT STDCALL CEnumMediaTypes_Reset(IEnumMediaTypes * This) -{ - Debug printf("CEnumMediaTypes::Reset(%p) called\n", This); - return 0; -} - -/** - * \brief IEnumMediaTypes::Clone (makes a copy of enumerator, returned object - * starts at the same position as original) - * - * \param[in] This pointer to CEnumMEdiaTypes object - * \param[out] ppEnum address of variable that receives pointer to IEnumMediaTypes interface - * - * \return S_OK - success - * \return E_OUTOFMEMRY - Insufficient memory - * \return E_POINTER - Null pointer - * \return VFW_E_ENUM_OUT_OF_SYNC - pin's state has changed and is now inconsistent with enumerator - * - */ -static HRESULT STDCALL CEnumMediaTypes_Clone(IEnumMediaTypes * This, - /* [out] */ IEnumMediaTypes **ppEnum) -{ - Debug printf("CEnumMediaTypes::Clone(%p) called\n", This); - return E_NOTIMPL; -} - -/** - * \brief CEnumMediaTypes destructor - * - * \param[in] This pointer to CEnumMediaTypes object - * - */ -static void CEnumMediaTypes_Destroy(CEnumMediaTypes* This) -{ - FreeMediaType(&(This->type)); - free(This->vt); - free(This); -} - -// IEnumMediaTypes->IUnknown methods -IMPLEMENT_IUNKNOWN(CEnumMediaTypes) - -/** - * \brief CEnumMediaTypes constructor - * - * \param[in] amt media type for enumerating - * - * \return pointer to CEnumMEdiaTypes object or NULL if error occured - * - */ -static CEnumMediaTypes* CEnumMediaTypesCreate(const AM_MEDIA_TYPE* amt) -{ - CEnumMediaTypes *This = malloc(sizeof(CEnumMediaTypes)) ; - - if (!This) - return NULL; - - This->vt = malloc(sizeof(IEnumMediaTypes_vt)); - if (!This->vt) - { - free(This); - return NULL; - } - - This->refcount = 1; - CopyMediaType(&(This->type),amt); - - This->vt->QueryInterface = CEnumMediaTypes_QueryInterface; - This->vt->AddRef = CEnumMediaTypes_AddRef; - This->vt->Release = CEnumMediaTypes_Release; - This->vt->Next = CEnumMediaTypes_Next; - This->vt->Skip = CEnumMediaTypes_Skip; - This->vt->Reset = CEnumMediaTypes_Reset; - This->vt->Clone = CEnumMediaTypes_Clone; - - This->interfaces[0] = IID_IUnknown; - This->interfaces[1] = IID_IEnumMediaTypes; - - return This; -} - - -/************* - * COutputPin - * - * WARNING: - * This is implementation of INPUT pin in DirectShow's terms - * - *************/ - - -/** - * - * \brief IUnknown::QueryInterface (query object for interface) - * \param[in] This pointer to IUnknown interface - * \param[in] iid GUID of requested interface - * \param[out] ppv receives pointer to interface - * - * \return S_OK - success (and *ppv contains valid pointer) - * \return E_NOINTERFACE - interface not found (and *ppv was set NULL) - * - * \note - * Make sure to call Release on received interface when you are done - * - */ -static HRESULT STDCALL COutputPin_QueryInterface(IUnknown* This, const GUID* iid, void** ppv) -{ - COutputPin* p = (COutputPin*) This; - - Debug printf("COutputPin_QueryInterface(%p) called\n", This); - if (!ppv) - return E_INVALIDARG; - - if (memcmp(iid, &IID_IUnknown, 16) == 0) - { - *ppv = p; - p->vt->AddRef(This); - return 0; - } - if (memcmp(iid, &IID_IMemInputPin, 16) == 0) - { - *ppv = p->mempin; - p->mempin->vt->AddRef((IUnknown*)*ppv); - return 0; - } - - Debug printf("Unknown interface : %08x-%04x-%04x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x\n", - iid->f1, iid->f2, iid->f3, - (unsigned char)iid->f4[1], (unsigned char)iid->f4[0], - (unsigned char)iid->f4[2], (unsigned char)iid->f4[3], - (unsigned char)iid->f4[4], (unsigned char)iid->f4[5], - (unsigned char)iid->f4[6], (unsigned char)iid->f4[7]); - return E_NOINTERFACE; -} - -// IPin methods - -/** - * \brief IPin::Connect (connects pin to another pin) - * - * \param[in] This pointer to IPin interface - * \param[in] pReceivePin pointer to IPin interface of remote pin - * \param[in] pmt suggested media type for link. Can be NULL (any media type) - * - * \return S_OK - success. - * \return VFW_E_ALREADY_CONNECTED - pin already connected - * \return VFW_E_NOT_STOPPED - filter is active - * \return VFW_E_TYPE_NOT_ACCEPT - type is not acceptable - * \return Apropriate error code otherwise. - * - */ -static HRESULT STDCALL COutputPin_Connect(IPin * This, - /* [in] */ IPin *pReceivePin, - /* [in] */ /* const */ AM_MEDIA_TYPE *pmt) -{ - Debug printf("COutputPin_Connect(%p) called\n",This); -/* - *pmt=((COutputPin*)This)->type; - if(pmt->cbFormat>0) - { - pmt->pbFormat=malloc(pmt->cbFormat); - memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat); - } -*/ - //return E_NOTIMPL; - return 0;// XXXXXXXXXXXXX CHECKME XXXXXXXXXXXXXXX - // if I put return 0; here, it crashes -} - -/** - * \brief IPin::ReceiveConnection (accepts a connection from another pin) - * - * \param[in] This pointer to IPin interface - * \param[in] pConnector connecting pin's IPin interface - * \param[in] pmt suggested media type for connection - * - * \return S_OK - success - * \return E_POINTER - Null pointer - * \return VFW_E_ALREADY_CONNECTED - pin already connected - * \return VFW_E_NOT_STOPPED - filter is active - * \return VFW_E_TYPE_NOT_ACCEPT - type is not acceptable - * - * \note - * When returning S_OK method should also do the following: - * - store media type and return the same type in IPin::ConnectionMediaType - * - store pConnector and return it in IPin::ConnectedTo - * - */ -static HRESULT STDCALL COutputPin_ReceiveConnection(IPin * This, - /* [in] */ IPin *pConnector, - /* [in] */ const AM_MEDIA_TYPE *pmt) -{ - Debug printf("COutputPin_ReceiveConnection(%p) called\n", This); - ((COutputPin*)This)->remote = pConnector; - return 0; -} - -/** - * \brief IPin::Disconnect (accepts a connection from another pin) - * - * \param[in] This pointer to IPin interface - * - * \return S_OK - success - * \return S_FALSE - pin was not connected - * \return VFW_E_NOT_STOPPED - filter is active - * - * \note - * To break connection you have to also call Disconnect on other pin - */ -static HRESULT STDCALL COutputPin_Disconnect(IPin * This) -{ - Debug printf("COutputPin_Disconnect(%p) called\n", This); - return 1; -} - -/** - * \brief IPin::ConnectedTo (retrieves pointer to the connected pin, if such exist) - * - * \param[in] This pointer to IPin interface - * \param[out] pPin pointer to remote pin's IPin interface - * - * \return S_OK - success - * \return E_POINTER - Null pointer - * \return VFW_E_NOT_CONNECTED - pin is not connected - * - * \note - * Caller must call Release on received IPin, when done - */ -static HRESULT STDCALL COutputPin_ConnectedTo(IPin * This, - /* [out] */ IPin **pPin) -{ - Debug printf("COutputPin_ConnectedTo(%p) called\n", This); - if (!pPin) - return E_INVALIDARG; - *pPin = ((COutputPin*)This)->remote; - return 0; -} - -/** - * \brief IPin::ConnectionMediaType (retrieves media type for connection, if such exist) - * - * \param[in] This pointer to IPin interface - * \param[out] pmt pointer to AM_MEDIA_TYPE, that receives connection media type - * - * \return S_OK - success - * \return E_POINTER - Null pointer - * \return VFW_E_NOT_CONNECTED - pin is not connected - * - */ -static HRESULT STDCALL COutputPin_ConnectionMediaType(IPin * This, - /* [out] */ AM_MEDIA_TYPE *pmt) -{ - Debug printf("COutputPin_ConnectionMediaType(%p) called\n",This); - if (!pmt) - return E_INVALIDARG; - CopyMediaType(pmt,&(((COutputPin*)This)->type)); - return 0; -} - -/** - * \brief IPin::QueryPinInfo (retrieves information about the pin) - * - * \param[in] This pointer to IPin interface - * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info - * - * \return S_OK - success - * \return E_POINTER - Null pointer - * - * \note - * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done - * - */ -static HRESULT STDCALL COutputPin_QueryPinInfo(IPin * This, - /* [out] */ PIN_INFO *pInfo) -{ - return output_unimplemented("COutputPin_QueryPinInfo", This); -} - -/** - * \brief IPin::QueryDirection (retrieves pin direction) - * - * \param[in] This pointer to IPin interface - * \param[out] pPinDir pointer to variable, that receives pin direction (PINDIR_INPUT,PINDIR_OUTPUT) - * - * \return S_OK - success - * \return E_POINTER - Null pointer - * - */ -static HRESULT STDCALL COutputPin_QueryDirection(IPin * This, - /* [out] */ PIN_DIRECTION *pPinDir) -{ - Debug printf("COutputPin_QueryDirection(%p) called\n", This); - if (!pPinDir) - return E_INVALIDARG; - *pPinDir = PINDIR_INPUT; - return 0; -} - -/** - * \brief IPin::QueryId (retrieves pin identificator) - * - * \param[in] This pointer to IPin interface - * \param[out] Id adress of variable, that receives string with pin's Id. - * - * \return S_OK - success - * \return E_OUTOFMEMORY - Insufficient memory - * \return E_POINTER - Null pointer - * - * \note - * Pin's Id is not the same as pin's name - * - */ -static HRESULT STDCALL COutputPin_QueryId(IPin * This, - /* [out] */ LPWSTR *Id) -{ - return output_unimplemented("COutputPin_QueryId", This); -} - -/** - * \brief IPin::QueryAccept (determines can media type be accepted or not) - * - * \param[in] This pointer to IPin interface - * \param[in] pmt Media type to check - * - * \return S_OK - success - * \return S_FALSE - pin rejects media type - * - */ -static HRESULT STDCALL COutputPin_QueryAccept(IPin * This, - /* [in] */ const AM_MEDIA_TYPE *pmt) -{ - return output_unimplemented("COutputPin_QueryAccept", This); -} - -/** - * \brief IPin::EnumMediaTypes (enumerates the pin's preferred media types) - * - * \param[in] This pointer to IPin interface - * \param[out] ppEnum adress of variable that receives pointer to IEnumMEdiaTypes interface - * - * \return S_OK - success - * \return E_OUTOFMEMORY - Insufficient memory - * \return E_POINTER - Null pointer - * - * \note - * Caller must call Release on received interface when done - * - */ -static HRESULT STDCALL COutputPin_EnumMediaTypes(IPin * This, - /* [out] */ IEnumMediaTypes **ppEnum) -{ - Debug printf("COutputPin_EnumMediaTypes(%p) called\n",This); - if (!ppEnum) - return E_INVALIDARG; - *ppEnum = (IEnumMediaTypes*) CEnumMediaTypesCreate(&((COutputPin*)This)->type); - return 0; -} - -/** - * \brief IPin::QueryInternalConnections (retries pin's internal connections) - * - * \param[in] This pointer to IPin interface - * \param[out] apPin Array that receives pins, internally connected to this - * \param[in,out] nPint Size of an array - * - * \return S_OK - success - * \return S_FALSE - pin rejects media type - * \return E_NOTIMPL - not implemented - * - */ -static HRESULT STDCALL COutputPin_QueryInternalConnections(IPin * This, - /* [out] */ IPin **apPin, - /* [out][in] */ ULONG *nPin) -{ - return output_unimplemented("COutputPin_QueryInternalConnections", This); -} - -/** - * \brief IPin::EndOfStream (notifies pin, that no data is expected, until new run command) - * - * \param[in] This pointer to IPin interface - * - * \return S_OK - success - * \return E_UNEXPECTED - The pin is output pin - * - * \note - * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream, - * IMemAllocator::GetBuffer runs in different (streaming) thread then other - * methods (application thread). - * IMemoryInputPin::NewSegment runs either in streaming or application thread. - * Developer must use critical sections for thread-safing work. - * - */ -static HRESULT STDCALL COutputPin_EndOfStream(IPin * This) -{ - return output_unimplemented("COutputPin_EndOfStream", This); -} - -/** - * \brief IPin::BeginFlush (begins a flush operation) - * - * \param[in] This pointer to IPin interface - * - * \return S_OK - success - * \return E_UNEXPECTED - The pin is output pin - * - */ -static HRESULT STDCALL COutputPin_BeginFlush(IPin * This) -{ - return output_unimplemented("COutputPin_BeginFlush", This); -} - -/** - * \brief IPin::EndFlush (ends a flush operation) - * - * \param[in] This pointer to IPin interface - * - * \return S_OK - success - * \return E_UNEXPECTED - The pin is output pin - * - */ -static HRESULT STDCALL COutputPin_EndFlush(IPin * This) -{ - return output_unimplemented("COutputPin_EndFlush", This); -} - -/** - * \brief IPin::NewSegment (media sample received after this call grouped as segment with common - * start,stop time and rate) - * - * \param[in] This pointer to IPin interface - * \param[in] tStart start time of new segment - * \param[in] tStop end time of new segment - * \param[in] dRate rate at wich segment should be processed - * - * \return S_OK - success - * \return E_UNEXPECTED - The pin is output pin - * - */ -static HRESULT STDCALL COutputPin_NewSegment(IPin * This, - /* [in] */ REFERENCE_TIME tStart, - /* [in] */ REFERENCE_TIME tStop, - /* [in] */ double dRate) -{ - Debug printf("COutputPin_NewSegment(%d,%d,%f) called\n", - (int)tStart, (int)tStop, dRate); - return 0; -} - - - -// IMemInputPin->IUnknown methods - -/** - * \brief IUnknown::QueryInterface (query object for interface) - * - * \param[in] This pointer to IUnknown interface - * \param[in] iid GUID of requested interface - * \param[out] ppv receives pointer to interface - * - * \return S_OK - success (and *ppv contains valid pointer) - * \return E_NOINTERFACE - interface not found (and *ppv was set NULL) - * - * \note - * Make sure to call Release on received interface when you are done - * - */ -static HRESULT STDCALL COutputMemPin_QueryInterface(IUnknown* This, const GUID* iid, void** ppv) -{ - COutputMemPin* p = (COutputMemPin*)This; - - Debug printf("COutputMemPin_QueryInterface(%p) called\n", This); - if (!ppv) - return E_INVALIDARG; - - if(!memcmp(iid, &IID_IUnknown, 16)) - { - *ppv = p; - p->vt->AddRef(This); - return 0; - } - /*if(!memcmp(iid, &IID_IPin, 16)) - { - COutputPin* ptr=(COutputPin*)(This-1); - *ppv=(void*)ptr; - AddRef((IUnknown*)ptr); - return 0; - }*/ - if(!memcmp(iid, &IID_IMemInputPin, 16)) - { - *ppv = p; - p->vt->AddRef(This); - return 0; - } - Debug printf("Unknown interface : %08x-%04x-%04x-%02x%02x-" \ - "%02x%02x%02x%02x%02x%02x\n", - iid->f1, iid->f2, iid->f3, - (unsigned char)iid->f4[1], (unsigned char)iid->f4[0], - (unsigned char)iid->f4[2], (unsigned char)iid->f4[3], - (unsigned char)iid->f4[4], (unsigned char)iid->f4[5], - (unsigned char)iid->f4[6], (unsigned char)iid->f4[7]); - return E_NOINTERFACE; -} - -// IMemInputPin methods - -/** - * \brief IMemInputPin::GetAllocator (retrives memory allocator, proposed by pin) - * - * \param[in] This pointer to IMemInputPin interface - * \param[out] ppAllocator address of variable that receives allocator's IMemAllocator interface - * - * \return S_OK - success - * \return VFW_E_NO_ALLOCATOR - No allocator - * - * \note - * Make sure to call Release on received interface when you are done - * - */ -static HRESULT STDCALL COutputMemPin_GetAllocator(IMemInputPin* This, - /* [out] */ IMemAllocator** ppAllocator) -{ - Debug printf("COutputMemPin_GetAllocator(%p, %p) called\n", This->vt, ppAllocator); - *ppAllocator = (IMemAllocator*) MemAllocatorCreate(); - return 0; -} - -/** - * - * \brief IMemInputPin::NotifyAllocator (specifies an allocator for the connection) - * - * \param[in] This pointer to IMemInputPin interface - * \param[in] pAllocator allocator's IMemAllocator interface - * \param[in] bReadOnly specifies whether samples from allocator are readonly - * - * \return S_OK - success - * \return Apropriate error code otherwise - * - */ -static HRESULT STDCALL COutputMemPin_NotifyAllocator(IMemInputPin* This, - /* [in] */ IMemAllocator* pAllocator, - /* [in] */ int bReadOnly) -{ - Debug printf("COutputMemPin_NotifyAllocator(%p, %p) called\n", This, pAllocator); - ((COutputMemPin*)This)->pAllocator = (MemAllocator*) pAllocator; - return 0; -} - -/** - * \brief IMemInputPin::GetAllocatorRequirements (retrieves allocator properties requested by - * input pin) - * - * \param[in] This pointer to IMemInputPin interface - * \param[out] pProps pointer to a structure that receives allocator properties - * - * \return S_OK - success - * \return E_NOTIMPL - Not implemented - * \return E_POINTER - Null pointer - * - */ -static HRESULT STDCALL COutputMemPin_GetAllocatorRequirements(IMemInputPin* This, - /* [out] */ ALLOCATOR_PROPERTIES* pProps) -{ - return output_unimplemented("COutputMemPin_GetAllocatorRequirements", This); -} - -/** - * \brief IMemInputPin::Receive (receives the next media sample int thre stream) - * - * \param[in] This pointer to IMemInputPin interface - * \param[in] pSample pointer to sample's IMediaSample interface - * - * \return S_OK - success - * \return S_FALSE - The sample was rejected - * \return E_POINTER - Null pointer - * \return VFW_E_INVALIDMEDIATYPE - invalid media type - * \return VFW_E_RUNTIME_ERROR - run-time error occured - * \return VFW_E_WRONG_STATE - pin is stopped - * - * \remarks - * Method san do on of the following: - * - reject sample - * - accept sample and process it in another thread - * - accept sample and process it before returning - * - * In second case method should increase reference count for sample (through AddRef) - * In the last case method might block indefinitely. If this might - * happen IMemInpuPin::ReceiveCAnBlock returns S_OK - * - * \note - * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream, - * IMemAllocator::GetBuffer runs in different (streaming) thread then other - * methods (application thread). - * IMemoryInputPin::NewSegment runs either in streaming or application thread. - * Developer must use critical sections for thread-safing work. - * - */ -static HRESULT STDCALL COutputMemPin_Receive(IMemInputPin* This, - /* [in] */ IMediaSample* pSample) -{ - Debug printf("COutputMemPin_Receive(%p) called\n", This); - if (!pSample) - return E_INVALIDARG; - - if(((COutputMemPin*)This)->parent->SampleProc) - return ((COutputMemPin*)This)->parent->SampleProc(((COutputMemPin*)This)->parent->pUserData,pSample); - //reject sample - return S_FALSE; -} - -/** - * \brief IMemInputPin::ReceiveMultiple (receives multiple samples in the stream) - * - * \param[in] This pointer to IMemInputPin interface - * \param[in] pSamples pointer to array with samples - * \param[in] nSamples number of samples in array - * \param[out] nSamplesProcessed number of processed samples - * - * \return S_OK - success - * \return S_FALSE - The sample was rejected - * \return E_POINTER - Null pointer - * \return VFW_E_INVALIDMEDIATYPE - invalid media type - * \return VFW_E_RUNTIME_ERROR - run-time error occured - * \return VFW_E_WRONG_STATE - pin is stopped - * - * \remarks - * This method behaves like IMemInputPin::Receive but for array of samples - * - * \note - * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream, - * IMemAllocator::GetBuffer runs in different (streaming) thread then other - * methods (application thread). - * IMemoryInputPin::NewSegment runs either in streaming or application thread. - * Developer must use critical sections for thread-safing work. - * - */ -static HRESULT STDCALL COutputMemPin_ReceiveMultiple(IMemInputPin * This, - /* [size_is][in] */ IMediaSample **pSamples, - /* [in] */ long nSamples, - /* [out] */ long *nSamplesProcessed) -{ - HRESULT hr = 0; - Debug printf("COutputMemPin_ReceiveMultiple(%p) %ld\n", This,nSamples); - for(*nSamplesProcessed=0; *nSamplesProcessed < nSamples; *nSamplesProcessed++) { - hr = This->vt->Receive(This,pSamples[*nSamplesProcessed]); - if (hr != S_OK) break; - } - return hr; -} - -/** - * \brief IMemInputPin::ReceiveCanBlock (determines whether IMemInputPin:::Receive might block) - * - * \param[in] This pointer to IMemInputPin interface - * - * \return S_OK - the pin might block - * \return S_FALSE - the pin will not block - * - */ -static HRESULT STDCALL COutputMemPin_ReceiveCanBlock(IMemInputPin * This) -{ - return output_unimplemented("COutputMemPin_ReceiveCanBlock", This); -} - -/** - * \brief COutputPin::SetNewFormat(sets new media format for the pin) - * - * \param[in] This pointer to COutputPin class - * \param[in] amt new media format - * - */ -static void COutputPin_SetNewFormat(COutputPin* This, const AM_MEDIA_TYPE* amt) -{ - CopyMediaType(&(This->type),amt); -} - -/** - * \brief COutputPin destructor - * - * \param[in] This pointer to COutputPin class - * - */ -static void COutputPin_Destroy(COutputPin* This) -{ - free(This->mempin->vt); - free(This->mempin); - free(This->vt); - FreeMediaType(&(This->type)); - free(This); -} - -/** - * \brief IUnknown::AddRef (increases reference counter for interface) - * - * \param[in] This pointer to IUnknown class - * - * \return new value of reference counter - * - * \remarks - * Return value should be used only for debug purposes - * - */ -static HRESULT STDCALL COutputPin_AddRef(IUnknown* This) -{ - Debug printf("COutputPin_AddRef(%p) called (%d)\n", This, ((COutputPin*)This)->refcount); - ((COutputPin*)This)->refcount++; - return 0; -} - -/** - * \brief IUnknown::Release (desreases reference counter for interface) - * - * \param[in] This pointer to IUnknown class - * - * \return new value of reference counter - * - * \remarks - * When reference counter reaches zero calls destructor - * Return value should be used only for debug purposes - * - */ -static HRESULT STDCALL COutputPin_Release(IUnknown* This) -{ - Debug printf("COutputPin_Release(%p) called (%d)\n", This, ((COutputPin*)This)->refcount); - if (--((COutputPin*)This)->refcount <= 0) - COutputPin_Destroy((COutputPin*)This); - - return 0; -} - -/** - * \brief IUnknown::AddRef (increases reference counter for interface) - * - * \param[in] This pointer to IUnknown class - * - * \return new value of reference counter - * - * \remarks - * Return value should be used only for debug purposes - * - */ -static HRESULT STDCALL COutputMemPin_AddRef(IUnknown* This) -{ - COutputMemPin* p = (COutputMemPin*) This; - Debug printf("COutputMemPin_AddRef(%p) called (%p, %d)\n", p, p->parent, p->parent->refcount); - p->parent->refcount++; - return 0; -} - -/** - * \brief IUnknown::Release (desreases reference counter for interface) - * - * \param[in] This pointer to IUnknown class - * - * \return new value of reference counter - * - * \remarks - * When reference counter reaches zero calls destructor - * Return value should be used only for debug purposes - * - */ -static HRESULT STDCALL COutputMemPin_Release(IUnknown* This) -{ - COutputMemPin* p = (COutputMemPin*) This; - Debug printf("COutputMemPin_Release(%p) called (%p, %d)\n", - p, p->parent, p->parent->refcount); - if (--p->parent->refcount <= 0) - COutputPin_Destroy(p->parent); - return 0; -} - -/** - * \brief COutputPin constructor - * - * \param[in] amt media type for pin - * - * \return pointer to COutputPin if success - * \return NULL if error occured - * - */ -COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* amt,SAMPLEPROC SampleProc,void* pUserData) -{ - COutputPin* This = malloc(sizeof(COutputPin)); - IMemInputPin_vt* ivt; - - if (!This) - return NULL; - - This->vt = malloc(sizeof(IPin_vt)); - This->mempin = malloc(sizeof(COutputMemPin)); - ivt = malloc(sizeof(IMemInputPin_vt)); - - if (!This->vt || !This->mempin || !ivt) - { - COutputPin_Destroy(This); - free(ivt); - return NULL; - } - - This->SampleProc=SampleProc; - This->pUserData=pUserData; - - This->mempin->vt = ivt; - - This->refcount = 1; - This->remote = 0; - CopyMediaType(&(This->type),amt); - - This->vt->QueryInterface = COutputPin_QueryInterface; - This->vt->AddRef = COutputPin_AddRef; - This->vt->Release = COutputPin_Release; - This->vt->Connect = COutputPin_Connect; - This->vt->ReceiveConnection = COutputPin_ReceiveConnection; - This->vt->Disconnect = COutputPin_Disconnect; - This->vt->ConnectedTo = COutputPin_ConnectedTo; - This->vt->ConnectionMediaType = COutputPin_ConnectionMediaType; - This->vt->QueryPinInfo = COutputPin_QueryPinInfo; - This->vt->QueryDirection = COutputPin_QueryDirection; - This->vt->QueryId = COutputPin_QueryId; - This->vt->QueryAccept = COutputPin_QueryAccept; - This->vt->EnumMediaTypes = COutputPin_EnumMediaTypes; - This->vt->QueryInternalConnections = COutputPin_QueryInternalConnections; - This->vt->EndOfStream = COutputPin_EndOfStream; - This->vt->BeginFlush = COutputPin_BeginFlush; - This->vt->EndFlush = COutputPin_EndFlush; - This->vt->NewSegment = COutputPin_NewSegment; - - This->mempin->vt->QueryInterface = COutputMemPin_QueryInterface; - This->mempin->vt->AddRef = COutputMemPin_AddRef; - This->mempin->vt->Release = COutputMemPin_Release; - This->mempin->vt->GetAllocator = COutputMemPin_GetAllocator; - This->mempin->vt->NotifyAllocator = COutputMemPin_NotifyAllocator; - This->mempin->vt->GetAllocatorRequirements = COutputMemPin_GetAllocatorRequirements; - This->mempin->vt->Receive = COutputMemPin_Receive; - This->mempin->vt->ReceiveMultiple = COutputMemPin_ReceiveMultiple; - This->mempin->vt->ReceiveCanBlock = COutputMemPin_ReceiveCanBlock; - - This->mempin->frame_size_pointer = 0; - This->mempin->frame_pointer = 0; - This->mempin->pAllocator = 0; - This->mempin->refcount = 1; - This->mempin->parent = This; - - This->SetNewFormat = COutputPin_SetNewFormat; - - return This; -} |