summaryrefslogtreecommitdiffstats
path: root/loader
diff options
context:
space:
mode:
authorarpi_esp <arpi_esp@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-03-20 00:05:27 +0000
committerarpi_esp <arpi_esp@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-03-20 00:05:27 +0000
commitfbe693a169b346b4b4e48ee39017cf86b594429b (patch)
treef2a0d6aae01e6a560ce75bba7f68f53890b5b9b9 /loader
parentcaf48a3f5da35dd2e183da9f34ed265bf082856f (diff)
downloadmpv-fbe693a169b346b4b4e48ee39017cf86b594429b.tar.bz2
mpv-fbe693a169b346b4b4e48ee39017cf86b594429b.tar.xz
Initial revision
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@169 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'loader')
-rw-r--r--loader/dshow/DS_Filter.c177
-rw-r--r--loader/dshow/DS_Filter.h39
-rw-r--r--loader/dshow/Makefile44
-rw-r--r--loader/dshow/allocator.c154
-rw-r--r--loader/dshow/allocator.h49
-rw-r--r--loader/dshow/cmediasample.c251
-rw-r--r--loader/dshow/cmediasample.h96
-rw-r--r--loader/dshow/guids.c61
-rw-r--r--loader/dshow/guids.h90
-rw-r--r--loader/dshow/inputpin.c667
-rw-r--r--loader/dshow/inputpin.h265
-rw-r--r--loader/dshow/interfaces.h417
-rw-r--r--loader/dshow/iunk.h47
-rw-r--r--loader/dshow/outputpin.c483
-rw-r--r--loader/dshow/outputpin.h122
-rw-r--r--loader/dshow/test.divxbin0 -> 9294 bytes
16 files changed, 2962 insertions, 0 deletions
diff --git a/loader/dshow/DS_Filter.c b/loader/dshow/DS_Filter.c
new file mode 100644
index 0000000000..51d1c126dc
--- /dev/null
+++ b/loader/dshow/DS_Filter.c
@@ -0,0 +1,177 @@
+#include <stdio.h>
+#include <string.h>
+#include "DS_Filter.h"
+#include <except.h>
+//#include "../loader/loader.h"
+#include <string>
+#define __MODULE__ "DirectShow generic filter"
+
+using namespace std;
+
+typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**);
+extern "C" char* def_path;
+
+extern "C" int STDCALL LoadLibraryA(const char*);
+extern "C" STDCALL void* GetProcAddress(int, const char*);
+extern "C" int STDCALL FreeLibrary(int);
+
+DS_Filter::DS_Filter()
+ :m_iHandle(0), m_pFilter(0), m_pInputPin(0),
+ m_pOutputPin(0), m_pSrcFilter(0),
+ m_pOurInput(0), m_pOurOutput(0),
+ m_pImp(0), m_pAll(0), m_pParentFilter(0)
+{
+}
+
+void DS_Filter::Create(string dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt)
+{
+ try
+ {
+ string _fullname=def_path;
+ _fullname+="/";
+ _fullname+=dllname;
+ m_iHandle= LoadLibraryA(_fullname.c_str());
+ if(!m_iHandle)throw FATAL("Could not open DLL");
+ GETCLASS func=(GETCLASS)GetProcAddress(m_iHandle, "DllGetClassObject");
+ if(!func)throw FATAL("Illegal or corrupt DLL");
+
+ HRESULT result;
+ IClassFactory* factory=0;
+ IUnknown* object=0;
+
+ result=func(id, &IID_IClassFactory, (void**)&factory);
+ if(result || (!factory)) throw FATAL("No such class object");;
+
+ printf("# factory = %X\n",(unsigned int)factory);
+ printf("# factory->vt = %X\n",(unsigned int)factory->vt);
+ printf("# factory->vt->CreateInstance = %X\n",(unsigned int)factory->vt->CreateInstance);
+
+ printf("Calling factory->vt->CreateInstance()\n");
+ result=factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object);
+ printf("Calling factory->vt->Release()\n");
+
+// result=factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object);
+
+ printf("CreateInstance ok %x\n",result);
+
+ factory->vt->Release((IUnknown*)factory);
+ if(result || (!object)) throw FATAL("Class factory failure");
+
+ result=object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&m_pFilter);
+ object->vt->Release((IUnknown*)object);
+ if(result || (!m_pFilter)) throw FATAL("Object does not have IBaseFilter interface");
+
+ IEnumPins* enum_pins=0;
+ // enumerate pins
+ result=m_pFilter->vt->EnumPins(m_pFilter, &enum_pins);
+ if(result || (!enum_pins)) throw FATAL("Could not enumerate pins");
+ IPin* array[256];
+ ULONG fetched;
+ enum_pins->vt->Reset(enum_pins);
+ result=enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched);
+ printf("Pins enumeration returned %d pins, error is %x\n", fetched, result);
+
+ for(int i=0; i<fetched; i++)
+ {
+ int direction=-1;
+ array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction);
+ if((!m_pInputPin)&&(direction==0))
+ {
+ m_pInputPin=array[i];
+ m_pInputPin->vt->AddRef((IUnknown*)m_pInputPin);
+ }
+ if((!m_pOutputPin)&&(direction==1))
+ {
+ m_pOutputPin=array[i];
+ m_pOutputPin->vt->AddRef((IUnknown*)m_pOutputPin);
+ }
+ array[i]->vt->Release((IUnknown*)(array[i]));
+ }
+ if(!m_pInputPin)throw FATAL("Input pin not found");
+ if(!m_pOutputPin)throw FATAL("Output pin not found");
+
+ result=m_pInputPin->vt->QueryInterface((IUnknown*)m_pInputPin, &IID_IMemInputPin, (void**)&m_pImp);
+ if(result)
+ throw FATAL("Error getting IMemInputPin interface");
+ m_pOurType=in_fmt;
+ m_pDestType=out_fmt;
+ result=m_pInputPin->vt->QueryAccept(m_pInputPin, m_pOurType);
+ if(result) throw FATAL("Source format is not accepted");
+
+ m_pParentFilter=new CBaseFilter2;
+ m_pSrcFilter=new CBaseFilter(*m_pOurType, m_pParentFilter);
+ m_pOurInput=m_pSrcFilter->GetPin();
+ m_pOurInput->vt->AddRef((IUnknown*)m_pOurInput);
+
+ result=m_pInputPin->vt->ReceiveConnection(m_pInputPin, m_pOurInput, m_pOurType);
+ if(result) throw FATAL("Error connecting to input pin");
+
+ m_pOurOutput=new COutputPin(*m_pDestType);
+ result=m_pOutputPin->vt->ReceiveConnection(m_pOutputPin,
+ m_pOurOutput, m_pDestType);
+ if(result)throw FATAL("Error connecting to output pin");
+ m_iState=1;
+ }
+ catch(FatalError e)
+ {
+ e.PrintAll();
+ if(m_pFilter)m_pFilter->vt->Release((IUnknown*)m_pFilter);
+ if(m_pOutputPin)m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin);
+ if(m_pInputPin)m_pInputPin->vt->Release((IUnknown*)m_pInputPin);
+ if(m_pImp)m_pImp->vt->Release((IUnknown*)m_pImp);
+ if(m_pOurInput)m_pOurInput->vt->Release((IUnknown*)m_pOurInput);
+ delete m_pSrcFilter;
+ delete m_pParentFilter;
+ delete m_pOurOutput;
+ if(m_iHandle)FreeLibrary(m_iHandle);
+ throw;
+ }
+}
+void DS_Filter::Start()
+{
+ if(m_iState!=1)
+ return;
+
+ HRESULT hr=m_pFilter->vt->Run(m_pFilter, 0);
+ if(hr!=0)
+ {
+ cerr<<"WARNING: m_Filter->Run() failed, error code "<<hex<<hr<<dec<<endl;
+ }
+ hr=m_pImp->vt->GetAllocator(m_pImp, &m_pAll);
+ if(hr)
+ {
+ cerr<<"Error getting IMemAllocator interface "<<hex<<hr<<dec<<endl;
+ m_pImp->vt->Release((IUnknown*)m_pImp);
+ return;
+ }
+ m_pImp->vt->NotifyAllocator(m_pImp, m_pAll, 0);
+ m_iState=2;
+ return;
+}
+void DS_Filter::Stop()
+{
+ if(m_iState!=2)
+ return;
+ m_pAll->vt->Release((IUnknown*)m_pAll);
+ m_pAll=0;
+ m_pFilter->vt->Stop(m_pFilter);
+ m_iState=1;
+ return;
+}
+DS_Filter::~DS_Filter()
+{
+ if(m_iState==0)
+ return;
+ if(m_iState==2)Stop();
+ if(m_pInputPin)m_pInputPin->vt->Disconnect(m_pInputPin);
+ if(m_pOutputPin)m_pOutputPin->vt->Disconnect(m_pOutputPin);
+ if(m_pFilter)m_pFilter->vt->Release((IUnknown*)m_pFilter);
+ if(m_pOutputPin)m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin);
+ if(m_pInputPin)m_pInputPin->vt->Release((IUnknown*)m_pInputPin);
+ if(m_pOurInput)m_pOurInput->vt->Release((IUnknown*)m_pOurInput);
+ if(m_pImp)m_pImp->vt->Release((IUnknown*)m_pImp);
+ delete m_pSrcFilter;
+ delete m_pParentFilter;
+ delete m_pOurOutput;
+ if(m_iHandle)FreeLibrary(m_iHandle);
+}
diff --git a/loader/dshow/DS_Filter.h b/loader/dshow/DS_Filter.h
new file mode 100644
index 0000000000..1cb5a4d211
--- /dev/null
+++ b/loader/dshow/DS_Filter.h
@@ -0,0 +1,39 @@
+#ifndef DS_Filter_H
+#define DS_Filter_H
+
+#include "interfaces.h"
+#include "inputpin.h"
+#include "outputpin.h"
+#include <string>
+using namespace std;
+/**
+ User will allocate and fill format structures, call Create(),
+ and then set up m_pAll.
+**/
+class DS_Filter
+{
+protected:
+public:
+ DS_Filter();
+ virtual ~DS_Filter();
+ void Create(string dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt);
+ void Start();
+ void Stop();
+ int m_iHandle;
+ IBaseFilter* m_pFilter;
+ IPin* m_pInputPin;
+ IPin* m_pOutputPin;
+
+ CBaseFilter* m_pSrcFilter;
+ CBaseFilter2* m_pParentFilter;
+ IPin* m_pOurInput;
+ COutputPin* m_pOurOutput;
+
+ AM_MEDIA_TYPE *m_pOurType, *m_pDestType;
+ IMemAllocator* m_pAll;
+ IMemInputPin* m_pImp;
+ int m_iState;
+protected:
+};
+
+#endif \ No newline at end of file
diff --git a/loader/dshow/Makefile b/loader/dshow/Makefile
new file mode 100644
index 0000000000..3970cfcfd4
--- /dev/null
+++ b/loader/dshow/Makefile
@@ -0,0 +1,44 @@
+
+LIBNAME = libDS_Filter.a
+
+include ../../config.mak
+
+SRCS = DS_Filter.cpp allocator.cpp cmediasample.cpp guids.cpp inputpin.cpp outputpin.cpp
+OBJS = DS_Filter.o allocator.o cmediasample.o guids.o inputpin.o outputpin.o
+
+INCLUDE = -I. -I.. -I../wine
+CFLAGS = $(OPTFLAGS) $(INCLUDE)
+
+.SUFFIXES: .cpp .o
+
+# .PHONY: all clean
+
+.cpp.o:
+ $(CC) -c $(CFLAGS) -o $@ $<
+
+$(LIBNAME): .depend $(OBJS)
+ $(AR) r $(LIBNAME) $(OBJS)
+
+test: test.cpp
+ $(CC) test.cpp $(CFLAGS) -o test -L. -lDS_Filter -L.. -lloader -ldl -lpthread -lstdc++
+
+all: $(LIBNAME)
+
+clean:
+ rm -f *.o *.a *~
+
+distclean:
+ rm -f Makefile.bak *.o *.a *~ .depend test test.raw
+
+dep: depend
+depend: .depend
+
+.depend: Makefile ../../config.mak
+ makedepend -f- -- $(CFLAGS) -- $(SRCS) 1>.depend 2>/dev/null
+
+#
+# include dependency files if they exist
+#
+ifneq ($(wildcard .depend),)
+include .depend
+endif
diff --git a/loader/dshow/allocator.c b/loader/dshow/allocator.c
new file mode 100644
index 0000000000..496d56c66f
--- /dev/null
+++ b/loader/dshow/allocator.c
@@ -0,0 +1,154 @@
+#include <stdio.h>
+#include "allocator.h"
+#include <com.h>
+#define E_NOTIMPL 0x80004001
+class AllocatorKeeper
+{
+public:
+ AllocatorKeeper()
+ {
+ RegisterComClass(&CLSID_MemoryAllocator, MemAllocator::CreateAllocator);
+ }
+};
+static AllocatorKeeper keeper;
+GUID MemAllocator::interfaces[]=
+{
+ IID_IUnknown,
+ IID_IMemAllocator,
+};
+IMPLEMENT_IUNKNOWN(MemAllocator)
+
+MemAllocator::MemAllocator()
+ :refcount(1)
+{
+ Debug printf("MemAllocator::MemAllocator() called\n");
+ vt=new IMemAllocator_vt;
+ vt->QueryInterface = QueryInterface;
+ vt->AddRef = AddRef;
+ vt->Release = Release;
+ vt->SetProperties = SetProperties;
+ vt->GetProperties = GetProperties;
+ vt->Commit = Commit;
+ vt->Decommit = Decommit;
+ vt->GetBuffer = GetBuffer;
+ vt->ReleaseBuffer = ReleaseBuffer;
+
+ props.cBuffers=1;
+ props.cbBuffer=65536;/* :/ */
+ props.cbAlign=props.cbPrefix=0;
+}
+
+long MemAllocator::CreateAllocator(GUID* clsid, GUID* iid, void** ppv)
+{
+ if(!ppv)return -1;
+ *ppv=0;
+ if(memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID)))
+ return -1;
+
+ IMemAllocator* p=new MemAllocator;
+ int result=p->vt->QueryInterface((IUnknown*)p, iid, ppv);
+ p->vt->Release((IUnknown*)p);
+ return result;
+}
+
+
+/*
+ long cBuffers;
+ long cbBuffer;
+ long cbAlign;
+ long cbPrefix;
+*/
+HRESULT STDCALL MemAllocator::SetProperties (
+ IMemAllocator * This,
+ /* [in] */ ALLOCATOR_PROPERTIES *pRequest,
+ /* [out] */ ALLOCATOR_PROPERTIES *pActual)
+{
+ Debug printf("MemAllocator::SetProperties() called\n");
+ if(!pRequest)return 0x80004003;
+ if(!pActual)return 0x80004003;
+ if(pRequest->cBuffers<=0)return -1;
+ if(pRequest->cbBuffer<=0)return -1;
+ MemAllocator* me=(MemAllocator*)This;
+ if(me->used_list.size() || me->free_list.size())return -1;
+ me->props=*pRequest;
+ *pActual=*pRequest;
+ return 0;
+}
+
+HRESULT STDCALL MemAllocator::GetProperties (
+ IMemAllocator * This,
+ /* [out] */ ALLOCATOR_PROPERTIES *pProps)
+{
+ Debug printf("MemAllocator::GetProperties() called\n");
+ if(!pProps)return -1;
+ if(((MemAllocator*)This)->props.cbBuffer<0)return -1;
+ *pProps=((MemAllocator*)This)->props;
+ return 0;
+}
+
+HRESULT STDCALL MemAllocator::Commit (
+ IMemAllocator * This)
+{
+ Debug printf("MemAllocator::Commit() called\n");
+ MemAllocator* me=(MemAllocator*)This;
+ if(((MemAllocator*)This)->props.cbBuffer<0)return -1;
+ if(me->used_list.size() || me->free_list.size())return -1;
+ for(int i=0; i<me->props.cBuffers; i++)
+ me->free_list.push_back(new CMediaSample(me, me->props.cbBuffer));
+ return 0;
+}
+
+HRESULT STDCALL MemAllocator::Decommit (
+ IMemAllocator * This)
+{
+ Debug printf("MemAllocator::Decommit() called\n");
+ MemAllocator* me=(MemAllocator*)This;
+ list<CMediaSample*>::iterator it;
+ for(it=me->free_list.begin(); it!=me->free_list.end(); it++)
+ delete *it;
+ for(it=me->used_list.begin(); it!=me->used_list.end(); it++)
+ delete *it;
+ me->free_list.clear();
+ me->used_list.clear();
+ return 0;
+}
+
+HRESULT STDCALL MemAllocator::GetBuffer (
+ IMemAllocator * This,
+ /* [out] */ IMediaSample **ppBuffer,
+ /* [in] */ REFERENCE_TIME *pStartTime,
+ /* [in] */ REFERENCE_TIME *pEndTime,
+ /* [in] */ DWORD dwFlags)
+{
+ Debug printf("%x: MemAllocator::GetBuffer() called\n", This);
+ MemAllocator* me=(MemAllocator*)This;
+ if(me->free_list.size()==0)
+ {
+ Debug printf("No samples available\n");
+ return -1;//should block here if no samples are available
+ }
+ list<CMediaSample*>::iterator it=me->free_list.begin();
+ me->used_list.push_back(*it);
+ *ppBuffer=*it;
+ (*ppBuffer)->vt->AddRef((IUnknown*)*ppBuffer);
+ me->free_list.remove(*it);
+ return 0;
+}
+
+HRESULT STDCALL MemAllocator::ReleaseBuffer (
+ IMemAllocator * This,
+ /* [in] */ IMediaSample *pBuffer)
+{
+ Debug printf("%x: MemAllocator::ReleaseBuffer() called\n", This);
+ MemAllocator* me=(MemAllocator*)This;
+ list<CMediaSample*>::iterator it;
+ for(it=me->used_list.begin(); it!=me->used_list.end(); it++)
+ if(*it==pBuffer)
+ {
+ me->used_list.erase(it);
+ me->free_list.push_back((CMediaSample*)pBuffer);
+ return 0;
+ }
+ Debug printf("Releasing unknown buffer\n");
+ return -1;
+}
diff --git a/loader/dshow/allocator.h b/loader/dshow/allocator.h
new file mode 100644
index 0000000000..0b4917a0a9
--- /dev/null
+++ b/loader/dshow/allocator.h
@@ -0,0 +1,49 @@
+#ifndef ALLOCATOR_H
+#define ALLOCATOR_H
+
+#include "interfaces.h"
+#include "cmediasample.h"
+#include <list>
+#include "iunk.h"
+#include "default.h"
+using namespace std;
+class MemAllocator: public IMemAllocator
+{
+ ALLOCATOR_PROPERTIES props;
+ list<CMediaSample*> used_list;
+ list<CMediaSample*> free_list;
+ static GUID interfaces[];
+ DECLARE_IUNKNOWN(MemAllocator)
+public:
+ MemAllocator();
+ ~MemAllocator(){delete vt;}
+ static long CreateAllocator(GUID* clsid, GUID* iid, void** ppv);
+
+ static HRESULT STDCALL SetProperties (
+ IMemAllocator * This,
+ /* [in] */ ALLOCATOR_PROPERTIES *pRequest,
+ /* [out] */ ALLOCATOR_PROPERTIES *pActual);
+
+ static HRESULT STDCALL GetProperties (
+ IMemAllocator * This,
+ /* [out] */ ALLOCATOR_PROPERTIES *pProps);
+
+ static HRESULT STDCALL Commit (
+ IMemAllocator * This);
+
+ static HRESULT STDCALL Decommit (
+ IMemAllocator * This);
+
+ static HRESULT STDCALL GetBuffer (
+ IMemAllocator * This,
+ /* [out] */ IMediaSample **ppBuffer,
+ /* [in] */ REFERENCE_TIME *pStartTime,
+ /* [in] */ REFERENCE_TIME *pEndTime,
+ /* [in] */ DWORD dwFlags);
+
+ static HRESULT STDCALL ReleaseBuffer (
+ IMemAllocator * This,
+ /* [in] */ IMediaSample *pBuffer);
+};
+
+#endif
diff --git a/loader/dshow/cmediasample.c b/loader/dshow/cmediasample.c
new file mode 100644
index 0000000000..c54774ad82
--- /dev/null
+++ b/loader/dshow/cmediasample.c
@@ -0,0 +1,251 @@
+#include <stdio.h>
+#include <string.h>
+#include "cmediasample.h"
+#define E_NOTIMPL 0x80004003
+CMediaSample::CMediaSample(IMemAllocator* allocator, long _size):refcount(0)
+{
+ vt=new IMediaSample_vt;
+
+ vt->QueryInterface=QueryInterface;
+ vt->AddRef=AddRef;
+ vt->Release=Release;
+ vt->GetPointer=GetPointer ;
+ vt->GetSize=GetSize ;
+ vt->GetTime=GetTime ;
+ vt->SetTime=SetTime ;
+ vt->IsSyncPoint=IsSyncPoint ;
+ vt->SetSyncPoint=SetSyncPoint;
+ vt->IsPreroll=IsPreroll;
+ vt->SetPreroll=SetPreroll;
+ vt->GetActualDataLength=GetActualDataLength;
+ vt->SetActualDataLength=SetActualDataLength;
+ vt->GetMediaType=GetMediaType;
+ vt->SetMediaType=SetMediaType;
+ vt->IsDiscontinuity=IsDiscontinuity;
+ vt->SetDiscontinuity=SetDiscontinuity;
+ vt->GetMediaTime=GetMediaTime;
+ vt->SetMediaTime=SetMediaTime;
+
+ all=allocator;
+ size=_size;
+ actual_size=0;
+ media_type.pbFormat=0;
+ isPreroll=0;
+ type_valid=0;
+ block=new char[size];
+ Debug printf("%x: Creating media sample with size %d, buffer 0x%x\n", this, _size, block);
+}
+CMediaSample::~CMediaSample()
+{
+ Debug printf("%x: CMediaSample::~CMediaSample() called\n", this);
+ delete vt;
+ delete[] block;
+ if(media_type.pbFormat)
+ CoTaskMemFree(media_type.pbFormat);
+}
+
+long STDCALL CMediaSample::QueryInterface (
+ IUnknown * This,
+ /* [in] */ IID* iid,
+ /* [iid_is][out] */ void **ppv)
+{
+ Debug printf("CMediaSample::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_IMediaSample, 16))
+ {
+ *ppv=(void*)This;
+ This->vt->AddRef(This);
+ return 0;
+ }
+ return 0x80004002;
+}
+
+long STDCALL CMediaSample::AddRef (
+ IUnknown * This)
+{
+ Debug printf("CMediaSample::AddRef() called\n");
+ ((CMediaSample*)This)->refcount++;
+ return 0;
+}
+
+long STDCALL CMediaSample::Release (
+ IUnknown * This)
+{
+ Debug printf("%x: CMediaSample::Release() called, new refcount %d\n", This,
+ ((CMediaSample*)This)->refcount-1);
+ CMediaSample* parent=(CMediaSample*)This;
+ if(--((CMediaSample*)This)->refcount==0)
+ parent->
+ all->
+ vt->
+ ReleaseBuffer(
+ (IMemAllocator*)(parent->all),
+ (IMediaSample*)This);
+ return 0;
+}
+HRESULT STDCALL CMediaSample::GetPointer (
+ IMediaSample * This,
+ /* [out] */ BYTE **ppBuffer)
+{
+ Debug printf("%x: CMediaSample::GetPointer() called\n", This);
+ if(!ppBuffer)return 0x80004003;
+ *ppBuffer=(BYTE *)((CMediaSample*)This)->block;
+ return 0;
+}
+
+long STDCALL CMediaSample::GetSize (
+ IMediaSample * This)
+{
+ Debug printf("%x: CMediaSample::GetSize() called -> %d\n", This, ((CMediaSample*)This)->size);
+ return ((CMediaSample*)This)->size;
+}
+
+HRESULT STDCALL CMediaSample::GetTime (
+ IMediaSample * This,
+ /* [out] */ REFERENCE_TIME *pTimeStart,
+ /* [out] */ REFERENCE_TIME *pTimeEnd)
+{
+ Debug printf("%x: CMediaSample::GetTime() called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL CMediaSample::SetTime (
+ IMediaSample * This,
+ /* [in] */ REFERENCE_TIME *pTimeStart,
+ /* [in] */ REFERENCE_TIME *pTimeEnd)
+{
+ Debug printf("%x: CMediaSample::SetTime() called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL CMediaSample::IsSyncPoint (
+ IMediaSample * This)
+{
+ Debug printf("%x: CMediaSample::IsSyncPoint() called\n", This);
+ if(((CMediaSample*)This)->isSyncPoint)return 0;
+ return 1;
+}
+
+HRESULT STDCALL CMediaSample::SetSyncPoint (
+ IMediaSample * This,
+ long bIsSyncPoint)
+{
+ Debug printf("%x: CMediaSample::SetSyncPoint() called\n", This);
+ ((CMediaSample*)This)->isSyncPoint=bIsSyncPoint;
+ return 0;
+}
+
+HRESULT STDCALL CMediaSample::IsPreroll (
+ IMediaSample * This)
+{
+ Debug printf("%x: CMediaSample::IsPreroll() called\n", This);
+ if(((CMediaSample*)This)->isPreroll==0)
+ return 1;//S_FALSE
+ else
+ return 0;//S_OK
+}
+
+HRESULT STDCALL CMediaSample::SetPreroll (
+ IMediaSample * This,
+ long bIsPreroll)
+{
+ Debug printf("%x: CMediaSample::SetPreroll() called\n", This);
+ ((CMediaSample*)This)->isPreroll=bIsPreroll;
+ return 0;
+}
+
+long STDCALL CMediaSample::GetActualDataLength (
+ IMediaSample * This)
+{
+ Debug printf("%x: CMediaSample::GetActualDataLength() called -> %d\n", This, ((CMediaSample*)This)->actual_size);
+ return ((CMediaSample*)This)->actual_size;
+}
+
+HRESULT STDCALL CMediaSample::SetActualDataLength (
+ IMediaSample * This,
+ long __MIDL_0010)
+{
+ Debug printf("%x: CMediaSample::SetActualDataLength(%d) called\n", This, __MIDL_0010);
+ if(__MIDL_0010>((CMediaSample*)This)->size)
+ {
+ printf("%x: ERROR: CMediaSample buffer overflow\n", This);
+ }
+ ((CMediaSample*)This)->actual_size=__MIDL_0010;
+ return 0;
+}
+
+HRESULT STDCALL CMediaSample::GetMediaType (
+ IMediaSample * This,
+ AM_MEDIA_TYPE **ppMediaType)
+{
+ Debug printf("%x: CMediaSample::GetMediaType() called\n", This);
+ if(!ppMediaType)
+ return 0x80004003;
+ if(!((CMediaSample*)This)->type_valid)
+ {
+ *ppMediaType=0;
+ return 1;
+ }
+ AM_MEDIA_TYPE& t=((CMediaSample*)This)->media_type;
+// if(t.pbFormat)CoTaskMemFree(t.pbFormat);
+ (*ppMediaType)=(AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+ memcpy(*ppMediaType, &t, sizeof(AM_MEDIA_TYPE));
+ (*ppMediaType)->pbFormat=(char*)CoTaskMemAlloc(t.cbFormat);
+ memcpy((*ppMediaType)->pbFormat, t.pbFormat, t.cbFormat);
+// *ppMediaType=0; //media type was not changed
+ return 0;
+}
+
+HRESULT STDCALL CMediaSample::SetMediaType (
+ IMediaSample * This,
+ AM_MEDIA_TYPE *pMediaType)
+{
+ Debug printf("%x: CMediaSample::SetMediaType() called\n", This);
+ if(!pMediaType)return 0x80004003;
+ AM_MEDIA_TYPE& t=((CMediaSample*)This)->media_type;
+ if(t.pbFormat)CoTaskMemFree(t.pbFormat);
+ t=*pMediaType;
+ t.pbFormat=(char*)CoTaskMemAlloc(t.cbFormat);
+ memcpy(t.pbFormat, pMediaType->pbFormat, t.cbFormat);
+ ((CMediaSample*)This)->type_valid=1;
+ return 0;
+}
+
+HRESULT STDCALL CMediaSample::IsDiscontinuity (
+ IMediaSample * This)
+{
+ Debug printf("%x: CMediaSample::IsDiscontinuity() called\n", This);
+ return 1;
+}
+
+HRESULT STDCALL CMediaSample::SetDiscontinuity (
+ IMediaSample * This,
+ long bDiscontinuity)
+{
+ Debug printf("%x: CMediaSample::SetDiscontinuity() called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL CMediaSample::GetMediaTime (
+ IMediaSample * This,
+ /* [out] */ LONGLONG *pTimeStart,
+ /* [out] */ LONGLONG *pTimeEnd)
+{
+ Debug printf("%x: CMediaSample::GetMediaTime() called\n", This);
+ return E_NOTIMPL;
+}
+
+HRESULT STDCALL CMediaSample::SetMediaTime (
+ IMediaSample * This,
+ /* [in] */ LONGLONG *pTimeStart,
+ /* [in] */ LONGLONG *pTimeEnd)
+{
+ Debug printf("%x: CMediaSample::SetMediaTime() called\n", This);
+ return E_NOTIMPL;
+}
diff --git a/loader/dshow/cmediasample.h b/loader/dshow/cmediasample.h
new file mode 100644
index 0000000000..3ad91330c7
--- /dev/null
+++ b/loader/dshow/cmediasample.h
@@ -0,0 +1,96 @@
+#ifndef _CMEDIASAMPLE_H
+#define _CMEDIASAMPLE_H
+
+#include "interfaces.h"
+#include "guids.h"
+#include "default.h"
+class CMediaSample: public IMediaSample
+{
+ IMemAllocator* all;
+ int size;
+ int actual_size;
+ char* block;
+ int refcount;
+ int isPreroll;
+ int isSyncPoint;
+ AM_MEDIA_TYPE media_type;
+ int type_valid;
+public:
+ CMediaSample(IMemAllocator* allocator, long _size);
+ ~CMediaSample();
+
+ static long STDCALL QueryInterface (
+ IUnknown * This,
+ /* [in] */ IID* riid,
+ /* [iid_is][out] */ void **ppvObject);
+
+ static long STDCALL AddRef (
+ IUnknown * This);
+
+ static long STDCALL Release (
+ IUnknown * This);
+
+ static HRESULT STDCALL GetPointer (
+ IMediaSample * This,
+ /* [out] */ BYTE **ppBuffer);
+
+ static long STDCALL GetSize (
+ IMediaSample * This);
+
+ static HRESULT STDCALL GetTime (
+ IMediaSample * This,
+ /* [out] */ REFERENCE_TIME *pTimeStart,
+ /* [out] */ REFERENCE_TIME *pTimeEnd);
+
+ static HRESULT STDCALL SetTime (
+ IMediaSample * This,
+ /* [in] */ REFERENCE_TIME *pTimeStart,
+ /* [in] */ REFERENCE_TIME *pTimeEnd);
+
+ static HRESULT STDCALL IsSyncPoint (
+ IMediaSample * This);
+
+ static HRESULT STDCALL SetSyncPoint (
+ IMediaSample * This,
+ long bIsSyncPoint);
+
+ static HRESULT STDCALL IsPreroll (
+ IMediaSample * This);
+
+ static HRESULT STDCALL SetPreroll (
+ IMediaSample * This,
+ long bIsPreroll);
+
+ static long STDCALL GetActualDataLength (
+ IMediaSample * This);
+
+ static HRESULT STDCALL SetActualDataLength (
+ IMediaSample * This,
+ long __MIDL_0010);
+
+ static HRESULT STDCALL GetMediaType (
+ IMediaSample * This,
+ AM_MEDIA_TYPE **ppMediaType);
+
+ static HRESULT STDCALL SetMediaType (
+ IMediaSample * This,
+ AM_MEDIA_TYPE *pMediaType);
+
+ static HRESULT STDCALL IsDiscontinuity (
+ IMediaSample * This);
+
+ static HRESULT STDCALL SetDiscontinuity (
+ IMediaSample * This,
+ long bDiscontinuity);
+
+ static HRESULT STDCALL GetMediaTime (
+ IMediaSample * This,
+ /* [out] */ LONGLONG *pTimeStart,
+ /* [out] */ LONGLONG *pTimeEnd);
+
+ static HRESULT STDCALL SetMediaTime (
+ IMediaSample * This,
+ /* [in] */ LONGLONG *pTimeStart,
+ /* [in] */ LONGLONG *pTimeEnd);
+};
+#endif
diff --git a/loader/dshow/guids.c b/loader/dshow/guids.c
new file mode 100644
index 0000000000..c9f9163e21
--- /dev/null
+++ b/loader/dshow/guids.c
@@ -0,0 +1,61 @@
+#include "guids.h"
+int DSHOW_DEBUG=0;
+
+GUID CLSID_DivxDecompressorCF={0x82CCd3E0, 0xF71A, 0x11D0,
+ { 0x9f, 0xe5, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa}};
+GUID CLSID_IV50_Decoder={0x30355649, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID IID_IBaseFilter={0x56a86895, 0x0ad4, 0x11ce,
+ {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+GUID IID_IEnumPins={0x56a86892, 0x0ad4, 0x11ce,
+ {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+GUID IID_IEnumMediaTypes={0x89c31040, 0x846b, 0x11ce,
+ {0x97, 0xd3, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
+GUID IID_IMemInputPin={0x56a8689d, 0x0ad4, 0x11ce,
+ {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+GUID IID_IMemAllocator={0x56a8689c, 0x0ad4, 0x11ce,
+ {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+GUID IID_IMediaSample={0x56a8689a, 0x0ad4, 0x11ce,
+ {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+
+GUID MEDIATYPE_Video={0x73646976, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID GUID_NULL={0x0, 0x0, 0x0,
+ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
+GUID FORMAT_VideoInfo={0x05589f80, 0xc356, 0x11ce,
+ {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
+GUID MEDIASUBTYPE_RGB565={0xe436eb7b, 0x524f, 0x11ce,
+ {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+GUID MEDIASUBTYPE_RGB555={0xe436eb7c, 0x524f, 0x11ce,
+ {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+GUID MEDIASUBTYPE_RGB24={0xe436eb7d, 0x524f, 0x11ce,
+ {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+GUID MEDIASUBTYPE_RGB32={0xe436eb7e, 0x524f, 0x11ce,
+ {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+GUID MEDIASUBTYPE_YUYV={0x56595559, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID MEDIASUBTYPE_IYUV={0x56555949, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID MEDIASUBTYPE_YVU9={0x39555659, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID MEDIASUBTYPE_Y411={0x31313459, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID MEDIASUBTYPE_Y41P={0x50313459, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID MEDIASUBTYPE_YUY2={0x32595559, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID MEDIASUBTYPE_YVYU={0x55595659, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID MEDIASUBTYPE_UYVY={0x59565955, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID MEDIASUBTYPE_Y211={0x31313259, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID MEDIASUBTYPE_YV12={0x32315659, 0x0000, 0x0010,
+ {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+GUID CLSID_MemoryAllocator={0x1e651cc0, 0xb199, 0x11d0,
+ {0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45}};
+GUID IID_DivxHidden={0x598eba01, 0xb49a, 0x11d2,
+ {0xa1, 0xc1, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa
+}};
+GUID IID_Iv50Hidden={0x665a4442, 0xd905, 0x11d0,
+ {0xa3, 0x0e, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};
diff --git a/loader/dshow/guids.h b/loader/dshow/guids.h
new file mode 100644
index 0000000000..3a9b63897b
--- /dev/null
+++ b/loader/dshow/guids.h
@@ -0,0 +1,90 @@
+#ifndef GUIDS_H
+#define GUIDS_H
+//#include <loader.h>
+//#include <wine/winbase.h>
+#include <com.h>
+#include <formats.h>
+extern int DSHOW_DEBUG;
+#define Debug if(DSHOW_DEBUG)
+
+struct IUnknown;
+typedef struct _MediaType
+{
+ GUID majortype; //0x0
+ GUID subtype; //0x10
+ int bFixedSizeSamples; //0x20
+ int bTemporalCompression; //0x24
+ unsigned long lSampleSize; //0x28
+ GUID formattype; //0x2c
+ IUnknown *pUnk; //0x3c
+ unsigned long cbFormat; //0x40
+ char *pbFormat; //0x44
+} AM_MEDIA_TYPE;
+typedef enum
+{
+ PINDIR_INPUT = 0,
+ PINDIR_OUTPUT = PINDIR_INPUT + 1
+} PIN_DIRECTION;
+typedef long long REFERENCE_TIME;
+//typedef long long LONGLONG;
+struct RECT32
+{
+ int left, top, right, bottom;
+};
+typedef struct tagVIDEOINFOHEADER {
+
+ RECT32 rcSource; // The bit we really want to use
+ RECT32 rcTarget; // Where the video should go
+ unsigned long dwBitRate; // Approximate bit data rate