diff options
author | arpi_esp <arpi_esp@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-03-20 00:05:27 +0000 |
---|---|---|
committer | arpi_esp <arpi_esp@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-03-20 00:05:27 +0000 |
commit | fbe693a169b346b4b4e48ee39017cf86b594429b (patch) | |
tree | f2a0d6aae01e6a560ce75bba7f68f53890b5b9b9 /loader | |
parent | caf48a3f5da35dd2e183da9f34ed265bf082856f (diff) | |
download | mpv-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.c | 177 | ||||
-rw-r--r-- | loader/dshow/DS_Filter.h | 39 | ||||
-rw-r--r-- | loader/dshow/Makefile | 44 | ||||
-rw-r--r-- | loader/dshow/allocator.c | 154 | ||||
-rw-r--r-- | loader/dshow/allocator.h | 49 | ||||
-rw-r--r-- | loader/dshow/cmediasample.c | 251 | ||||
-rw-r--r-- | loader/dshow/cmediasample.h | 96 | ||||
-rw-r--r-- | loader/dshow/guids.c | 61 | ||||
-rw-r--r-- | loader/dshow/guids.h | 90 | ||||
-rw-r--r-- | loader/dshow/inputpin.c | 667 | ||||
-rw-r--r-- | loader/dshow/inputpin.h | 265 | ||||
-rw-r--r-- | loader/dshow/interfaces.h | 417 | ||||
-rw-r--r-- | loader/dshow/iunk.h | 47 | ||||
-rw-r--r-- | loader/dshow/outputpin.c | 483 | ||||
-rw-r--r-- | loader/dshow/outputpin.h | 122 | ||||
-rw-r--r-- | loader/dshow/test.divx | bin | 0 -> 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 R |