📄 outputpin.c
字号:
/* * Modified for use with MPlayer, detailed changelog at * http://svn.mplayerhq.hu/mplayer/trunk/ */#include "wine/winerror.h"#include "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 methodsIMPLEMENT_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 = (CEnumMediaTypes*) malloc(sizeof(CEnumMediaTypes)) ; if (!This) return NULL; This->vt = (IEnumMediaTypes_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){ COutputPin *op = (COutputPin*)This; Debug printf("COutputPin_ReceiveConnection(%p) called\n", This); if(op->restrict_media_type && (memcmp(&pmt->majortype, &op->type.majortype, sizeof(GUID)) || memcmp(&pmt->subtype, &op->type.subtype, sizeof(GUID)))) { Debug printf("Refusing type 0x%08x\n", pmt->subtype.f1); return 0x8004022A; //VFW_E_TYPE_NOT_ACCEPT } ((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){ COutputPin *op = (COutputPin*)This; output_unimplemented("COutputPin_QueryAccept", This); if(op->restrict_media_type && (memcmp(&pmt->majortype, &op->type.majortype, sizeof(GUID)) || memcmp(&pmt->subtype, &op->type.subtype, sizeof(GUID)))) { Debug printf("Refusing type 0x%08x\n", pmt->subtype.f1); return S_FALSE; } if(memcmp(&pmt->formattype, &FORMAT_VideoInfo, sizeof(GUID))) { return S_OK; } if(memcmp(&pmt->formattype, &FORMAT_VideoInfo2, sizeof(GUID))) { return S_OK; } return S_FALSE;}/** * \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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -