diff loader/dshow/outputpin.c @ 168:bdc4a8fc04d8

Initial revision
author arpi_esp
date Tue, 20 Mar 2001 00:05:27 +0000
parents
children 9355b2ae634e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loader/dshow/outputpin.c	Tue Mar 20 00:05:27 2001 +0000
@@ -0,0 +1,483 @@
+#include "outputpin.h"
+#include <string.h>
+#include <stdio.h>
+#include "allocator.h"
+#include "iunk.h"
+#define E_NOTIMPL 0x80004001
+/*
+    An object beyond interface IEnumMediaTypes.
+    Returned by COutputPin through call IPin::EnumMediaTypes().
+*/
+
+class CEnumMediaTypes: public IEnumMediaTypes
+{
+    AM_MEDIA_TYPE type;
+    static GUID interfaces[];
+    DECLARE_IUNKNOWN(CEnumMediaTypes)
+public:
+    CEnumMediaTypes(const AM_MEDIA_TYPE&);
+    ~CEnumMediaTypes(){delete vt;}
+    static HRESULT STDCALL Next ( 
+        IEnumMediaTypes * This,
+        /* [in] */ ULONG cMediaTypes,
+        /* [size_is][out] */ AM_MEDIA_TYPE **ppMediaTypes,
+        /* [out] */ ULONG *pcFetched);
+    
+    static HRESULT STDCALL Skip ( 
+        IEnumMediaTypes * This,
+        /* [in] */ ULONG cMediaTypes);
+    
+    static HRESULT STDCALL Reset ( 
+        IEnumMediaTypes * This);
+    
+    static HRESULT STDCALL Clone ( 
+        IEnumMediaTypes * This,
+        /* [out] */ IEnumMediaTypes **ppEnum);
+
+};
+GUID CEnumMediaTypes::interfaces[]=
+{
+    IID_IUnknown,
+    IID_IEnumMediaTypes,
+};
+IMPLEMENT_IUNKNOWN(CEnumMediaTypes)
+CEnumMediaTypes::CEnumMediaTypes(const AM_MEDIA_TYPE& type)
+    :refcount(1)
+{
+    this->type=type;
+    vt=new IEnumMediaTypes_vt;
+    vt->QueryInterface = QueryInterface;
+    vt->AddRef = AddRef;
+    vt->Release = Release;
+    vt->Next = Next; 
+    vt->Skip = Skip; 
+    vt->Reset = Reset;
+    vt->Clone = Clone; 
+}
+
+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() called\n");
+    if(!ppMediaTypes)return 0x80004003;
+    if(!pcFetched && (cMediaTypes!=1))return 0x80004003;
+    if(cMediaTypes<=0)return 0;
+    
+    if(pcFetched)*pcFetched=1;
+    ppMediaTypes[0]=(AM_MEDIA_TYPE *)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+    memcpy(*ppMediaTypes, &type, sizeof(AM_MEDIA_TYPE));
+    if(ppMediaTypes[0]->pbFormat)
+    {
+	ppMediaTypes[0]->pbFormat=(char *)CoTaskMemAlloc(ppMediaTypes[0]->cbFormat);
+	memcpy(ppMediaTypes[0]->pbFormat, type.pbFormat, ppMediaTypes[0]->cbFormat);
+    }
+    if(cMediaTypes==1)return 0;
+    return 1;
+}
+/*
+    I expect that these methods are unused.
+*/
+HRESULT STDCALL CEnumMediaTypes::Skip ( 
+    IEnumMediaTypes * This,
+    /* [in] */ ULONG cMediaTypes)
+{
+    Debug printf("CEnumMediaTypes::Skip() called\n");
+    return E_NOTIMPL;
+}
+
+HRESULT STDCALL CEnumMediaTypes::Reset ( 
+    IEnumMediaTypes * This)
+{
+    Debug printf("CEnumMediaTypes::Reset() called\n");
+    return 0;
+}
+
+HRESULT STDCALL CEnumMediaTypes::Clone ( 
+    IEnumMediaTypes * This,
+    /* [out] */ IEnumMediaTypes **ppEnum)
+{
+    Debug printf("CEnumMediaTypes::Clone() called\n");
+    return E_NOTIMPL;
+}
+
+/*
+    Implementation of output pin object.
+*/
+
+// Constructor
+
+COutputPin::COutputPin(const AM_MEDIA_TYPE& vh) :refcount(1), type(vh), remote(0), frame_pointer(0), frame_size_pointer(0)
+{
+    IPin::vt=new IPin_vt;
+    IPin::vt->QueryInterface = QueryInterface;
+    IPin::vt->AddRef = AddRef;
+    IPin::vt->Release = Release;
+    IPin::vt->Connect = Connect;
+    IPin::vt->ReceiveConnection = ReceiveConnection;
+    IPin::vt->Disconnect=Disconnect;
+    IPin::vt->ConnectedTo = ConnectedTo;
+    IPin::vt->ConnectionMediaType = ConnectionMediaType;
+    IPin::vt->QueryPinInfo = QueryPinInfo;
+    IPin::vt->QueryDirection = QueryDirection;
+    IPin::vt->QueryId = QueryId;
+    IPin::vt->QueryAccept = QueryAccept;
+    IPin::vt->EnumMediaTypes = EnumMediaTypes;
+    IPin::vt->QueryInternalConnections = QueryInternalConnections;
+    IPin::vt->EndOfStream = EndOfStream;
+    IPin::vt->BeginFlush = BeginFlush;
+    IPin::vt->EndFlush = EndFlush;
+    IPin::vt->NewSegment = NewSegment;
+
+    IMemInputPin::vt=new IMemInputPin_vt;
+    IMemInputPin::vt->QueryInterface = M_QueryInterface;
+    IMemInputPin::vt->AddRef = M_AddRef;
+    IMemInputPin::vt->Release = M_Release;
+    IMemInputPin::vt->GetAllocator = GetAllocator;
+    IMemInputPin::vt->NotifyAllocator = NotifyAllocator;
+    IMemInputPin::vt->GetAllocatorRequirements = GetAllocatorRequirements;
+    IMemInputPin::vt->Receive = Receive;
+    IMemInputPin::vt->ReceiveMultiple = ReceiveMultiple;
+    IMemInputPin::vt->ReceiveCanBlock = ReceiveCanBlock;
+}
+
+// IPin->IUnknown methods
+
+HRESULT STDCALL COutputPin::QueryInterface(IUnknown* This, GUID* iid, void** ppv)
+{
+    Debug printf("COutputPin::QueryInterface() called\n");
+    if(!ppv)return 0x80004003;
+    if(!memcmp(iid, &IID_IUnknown, 16))
+    {
+	*ppv=(void*)This;
+	This->vt->AddRef(This);
+	return 0;
+    }
+    if(!memcmp(iid, &IID_IMemInputPin, 16))
+    {
+	*ppv=(void*)(This+1);
+	This->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 0x80004002;
+}
+HRESULT STDCALL COutputPin::AddRef(IUnknown* This)
+{
+    Debug printf("COutputPin::AddRef() called\n");
+    ((COutputPin*)This)->refcount++;
+    return 0;
+}
+HRESULT STDCALL COutputPin::Release(IUnknown* This)
+{
+    Debug printf("COutputPin::Release() called\n");
+    if(--((COutputPin*)This)->refcount==0)
+	delete (COutputPin*)This;
+    return 0;
+}
+
+// IPin methods
+
+HRESULT STDCALL COutputPin::Connect ( 
+    IPin * This,
+    /* [in] */ IPin *pReceivePin,
+    /* [in] */ /* const */ AM_MEDIA_TYPE *pmt)
+{
+    Debug printf("COutputPin::Connect() called\n");
+/*
+    *pmt=((COutputPin*)This)->type;
+    if(pmt->cbFormat>0)
+    {
+	pmt->pbFormat=CoTaskMemAlloc(pmt->cbFormat);
+	memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat);
+    }	
+*/
+    return E_NOTIMPL;
+    // if I put return 0; here, it crashes
+}
+
+HRESULT STDCALL COutputPin::ReceiveConnection ( 
+    IPin * This,
+    /* [in] */ IPin *pConnector,
+    /* [in] */ const AM_MEDIA_TYPE *pmt)
+{
+    Debug printf("COutputPin::ReceiveConnection() called\n");
+    ((COutputPin*)This)->remote=pConnector;
+    return 0;
+}
+	    
+HRESULT STDCALL COutputPin::Disconnect ( 
+    IPin * This)
+{
+    Debug printf("COutputPin::Disconnect() called\n");
+    return 1;
+}
+
+
+HRESULT STDCALL COutputPin::ConnectedTo ( 
+    IPin * This,
+    /* [out] */ IPin **pPin)
+{
+    Debug printf("COutputPin::ConnectedTo() called\n");
+    if(!pPin)return 0x80004003;
+    *pPin=((COutputPin*)This)->remote;
+    return 0;
+}
+
+
+
+HRESULT STDCALL COutputPin::ConnectionMediaType ( 
+    IPin * This,
+    /* [out] */ AM_MEDIA_TYPE *pmt)
+{
+    Debug printf("CInputPin::ConnectionMediaType() called\n");
+    if(!pmt)return 0x80004003;
+    *pmt=((COutputPin*)This)->type;
+    if(pmt->cbFormat>0)
+    {
+	pmt->pbFormat=(char *)CoTaskMemAlloc(pmt->cbFormat);
+	memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat);
+    }	
+    return 0;
+}
+
+HRESULT STDCALL COutputPin::QueryPinInfo ( 
+    IPin * This,
+    /* [out] */ PIN_INFO *pInfo)
+{
+    Debug printf("COutputPin::QueryPinInfo() called\n");
+    return E_NOTIMPL;
+}
+
+
+HRESULT STDCALL COutputPin::QueryDirection ( 
+    IPin * This,
+    /* [out] */ PIN_DIRECTION *pPinDir)
+{
+    Debug printf("COutputPin::QueryDirection() called\n");
+    if(!pPinDir)return -1;
+    *pPinDir=PINDIR_INPUT;
+    return 0;
+}
+
+
+HRESULT STDCALL COutputPin::QueryId ( 
+    IPin * This,
+    /* [out] */ LPWSTR *Id)
+{
+    Debug printf("COutputPin::QueryId() called\n");
+    return E_NOTIMPL;
+}
+
+
+HRESULT STDCALL COutputPin::QueryAccept ( 
+    IPin * This,
+    /* [in] */ const AM_MEDIA_TYPE *pmt)
+{
+    Debug printf("COutputPin::QueryAccept() called\n");
+    return E_NOTIMPL;
+}
+
+
+HRESULT STDCALL COutputPin::EnumMediaTypes ( 
+    IPin * This,
+    /* [out] */ IEnumMediaTypes **ppEnum)
+{
+    Debug printf("COutputPin::EnumMediaTypes() called\n");
+    if(!ppEnum)return 0x80004003;
+    *ppEnum=new CEnumMediaTypes(((COutputPin*)This)->type);
+    return 0;
+}
+
+
+HRESULT STDCALL COutputPin::QueryInternalConnections ( 
+    IPin * This,
+    /* [out] */ IPin **apPin,
+    /* [out][in] */ ULONG *nPin)
+{
+    Debug printf("COutputPin::QueryInternalConnections() called\n");
+    return E_NOTIMPL;
+}
+
+HRESULT STDCALL COutputPin::EndOfStream ( 
+    IPin * This)
+{
+    Debug printf("COutputPin::EndOfStream() called\n");
+    return E_NOTIMPL;
+}
+    
+    
+HRESULT STDCALL COutputPin::BeginFlush ( 
+IPin * This)
+{
+    Debug printf("COutputPin::BeginFlush() called\n");
+    return E_NOTIMPL;
+}
+
+
+HRESULT STDCALL COutputPin::EndFlush ( 
+    IPin * This)
+{
+    Debug printf("COutputPin::EndFlush() called\n");
+    return E_NOTIMPL;
+}
+
+HRESULT STDCALL COutputPin::NewSegment ( 
+    IPin * This,
+    /* [in] */ REFERENCE_TIME tStart,
+    /* [in] */ REFERENCE_TIME tStop,
+    /* [in] */ double dRate)
+{
+    Debug printf("COutputPin::NewSegment(%ld,%ld,%f) called\n",tStart,tStop,dRate);
+    return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// IMemInputPin->IUnknown methods
+
+HRESULT STDCALL COutputPin::M_QueryInterface(IUnknown* This, GUID* iid, void** ppv)
+{
+    Debug printf("COutputPin::QueryInterface() called\n");
+    if(!ppv)return 0x80004003;
+    if(!memcmp(iid, &IID_IUnknown, 16))
+    {
+	COutputPin* ptr=(COutputPin*)(This-1);
+	*ppv=(void*)ptr;
+	AddRef((IUnknown*)ptr);
+	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=(void*)This;
+	This->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 0x80004002;
+}
+HRESULT STDCALL COutputPin::M_AddRef(IUnknown* This)
+{
+    Debug printf("COutputPin::AddRef() called\n");
+    ((COutputPin*)(This-1))->refcount++;
+    return 0;
+}
+HRESULT STDCALL COutputPin::M_Release(IUnknown* This)
+{
+    Debug printf("COutputPin::Release() called\n");
+    if(--((COutputPin*)(This-1))->refcount==0)
+	delete (COutputPin*)This;
+    return 0;
+}
+
+
+
+
+// IMemInputPin methods
+
+HRESULT STDCALL COutputPin::GetAllocator( 
+        IMemInputPin * This,
+    /* [out] */ IMemAllocator **ppAllocator) 
+{
+    Debug printf("COutputPin::GetAllocator(%x,%x) called\n",This->vt,ppAllocator);
+    *ppAllocator=new MemAllocator;
+    return 0;
+}
+    
+HRESULT STDCALL COutputPin::NotifyAllocator( 
+        IMemInputPin * This,
+    /* [in] */ IMemAllocator *pAllocator,
+    /* [in] */ int bReadOnly)
+{
+    Debug printf("COutputPin::NotifyAllocator() called\n");
+    return 0;
+}
+
+HRESULT STDCALL COutputPin::GetAllocatorRequirements( 
+        IMemInputPin * This,
+    /* [out] */ ALLOCATOR_PROPERTIES *pProps) 
+{
+    Debug printf("COutputPin::GetAllocatorRequirements() called\n");
+    return E_NOTIMPL;
+}
+
+HRESULT STDCALL COutputPin::Receive( 
+        IMemInputPin * This,
+    /* [in] */ IMediaSample *pSample) 
+{
+    Debug printf("COutputPin::Receive() called\n");
+    COutputPin& me=*(COutputPin*)This;
+    if(!pSample)return 0x80004003;
+    char* pointer;
+    if(pSample->vt->GetPointer(pSample, (BYTE **)&pointer))
+	return -1;
+    int len=pSample->vt->GetActualDataLength(pSample);
+    if(len==0)len=pSample->vt->GetSize(pSample);//for iv50
+    //if(me.frame_pointer)memcpy(me.frame_pointer, pointer, len);
+    *me.frame_pointer=pointer;
+    if(me.frame_size_pointer)*me.frame_size_pointer=len;
+/*
+    FILE* file=fopen("./uncompr.bmp", "wb");
+    char head[14]={0x42, 0x4D, 0x36, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00};
+    *(int*)(&head[2])=len+0x36;
+    fwrite(head, 14, 1, file);
+    fwrite(&((VIDEOINFOHEADER*)me.type.pbFormat)->bmiHeader, sizeof(BITMAPINFOHEADER), 1, file);
+    fwrite(pointer, len, 1, file);
+    fclose(file);
+*/    
+//    pSample->vt->Release((IUnknown*)pSample);
+    return 0;
+}
+
+HRESULT STDCALL COutputPin::ReceiveMultiple( 
+        IMemInputPin * This,
+    /* [size_is][in] */ IMediaSample **pSamples,
+    /* [in] */ long nSamples,
+    /* [out] */ long *nSamplesProcessed)
+{
+    Debug printf("COutputPin::ReceiveMultiple() called\n");
+    return E_NOTIMPL;
+}
+
+HRESULT STDCALL COutputPin::ReceiveCanBlock(
+        IMemInputPin * This) 
+{
+    Debug printf("COutputPin::ReceiveCanBlock() called\n");
+    return E_NOTIMPL;
+}