summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libw32dll/DirectShow/DS_AudioDecoder.c172
-rw-r--r--src/libw32dll/DirectShow/DS_AudioDecoder.h36
-rw-r--r--src/libw32dll/DirectShow/DS_Filter.c237
-rw-r--r--src/libw32dll/DirectShow/DS_Filter.h42
-rw-r--r--src/libw32dll/DirectShow/Makefile.am36
-rw-r--r--src/libw32dll/DirectShow/allocator.c307
-rw-r--r--src/libw32dll/DirectShow/allocator.h51
-rw-r--r--src/libw32dll/DirectShow/cmediasample.c263
-rw-r--r--src/libw32dll/DirectShow/cmediasample.h34
-rw-r--r--src/libw32dll/DirectShow/guids.c64
-rw-r--r--src/libw32dll/DirectShow/guids.h96
-rw-r--r--src/libw32dll/DirectShow/inputpin.c682
-rw-r--r--src/libw32dll/DirectShow/inputpin.h211
-rw-r--r--src/libw32dll/DirectShow/interfaces.h346
-rw-r--r--src/libw32dll/DirectShow/iunk.h59
-rw-r--r--src/libw32dll/DirectShow/outputpin.c495
-rw-r--r--src/libw32dll/DirectShow/outputpin.h41
17 files changed, 3172 insertions, 0 deletions
diff --git a/src/libw32dll/DirectShow/DS_AudioDecoder.c b/src/libw32dll/DirectShow/DS_AudioDecoder.c
new file mode 100644
index 000000000..c86da0675
--- /dev/null
+++ b/src/libw32dll/DirectShow/DS_AudioDecoder.c
@@ -0,0 +1,172 @@
+/********************************************************
+
+ DirectShow audio decoder
+ Copyright 2001 Eugene Kuznetsov (divx@euro.ru)
+
+*********************************************************/
+#define NOAVIFILE_HEADERS
+
+#include "DS_AudioDecoder.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define __MODULE__ "DirectShow audio decoder"
+const GUID FORMAT_WaveFormatEx = {
+ 0x05589f81, 0xc356, 0x11CE,
+ { 0xBF, 0x01, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A }
+};
+const GUID MEDIATYPE_Audio = {
+ 0x73647561, 0x0000, 0x0010,
+ { 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }
+};
+const GUID MEDIASUBTYPE_PCM = {
+ 0x00000001, 0x0000, 0x0010,
+ { 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }
+};
+
+typedef long STDCALL (*GETCLASS) (GUID*, GUID*, void**);
+
+DS_AudioDecoder * DS_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf)
+{
+ DS_AudioDecoder *this;
+ int sz;
+ WAVEFORMATEX* pWF;
+
+ this = malloc(sizeof(DS_AudioDecoder));
+
+ sz = 18 + wf->cbSize;
+ this->m_sVhdr = malloc(sz);
+ memcpy(this->m_sVhdr, wf, sz);
+ this->m_sVhdr2 = malloc(sz);
+ memcpy(this->m_sVhdr2, this->m_sVhdr, sz);
+
+ pWF = (WAVEFORMATEX*)this->m_sVhdr2;
+ pWF->wFormatTag = 1;
+ pWF->wBitsPerSample = 16;
+ pWF->nBlockAlign = 2*pWF->nChannels;
+ pWF->cbSize = 0;
+
+ memcpy(&this->in_fmt,wf,sizeof(WAVEFORMATEX));
+
+ memset(&this->m_sOurType, 0, sizeof(this->m_sOurType));
+ this->m_sOurType.majortype=MEDIATYPE_Audio;
+ this->m_sOurType.subtype=MEDIASUBTYPE_PCM;
+ this->m_sOurType.subtype.f1=wf->wFormatTag;
+ this->m_sOurType.formattype=FORMAT_WaveFormatEx;
+ this->m_sOurType.lSampleSize=wf->nBlockAlign;
+ this->m_sOurType.bFixedSizeSamples=1;
+ this->m_sOurType.bTemporalCompression=0;
+ this->m_sOurType.pUnk=0;
+ this->m_sOurType.cbFormat=sz;
+ this->m_sOurType.pbFormat=this->m_sVhdr;
+
+ memset(&this->m_sDestType, 0, sizeof(this->m_sDestType));
+ this->m_sDestType.majortype=MEDIATYPE_Audio;
+ this->m_sDestType.subtype=MEDIASUBTYPE_PCM;
+ this->m_sDestType.formattype=FORMAT_WaveFormatEx;
+ this->m_sDestType.bFixedSizeSamples=1;
+ this->m_sDestType.bTemporalCompression=0;
+ this->m_sDestType.lSampleSize=2*wf->nChannels;
+ this->m_sDestType.pUnk=0;
+ this->m_sDestType.cbFormat=pWF->cbSize;
+ this->m_sDestType.pbFormat=this->m_sVhdr2;
+
+ /*try*/
+ {
+ ALLOCATOR_PROPERTIES props, props1;
+ this->m_pDS_Filter = DS_Filter_Create((const char*)info->dll, &info->guid, &this->m_sOurType, &this->m_sDestType);
+ DS_Filter_Start(this->m_pDS_Filter);
+
+ props.cBuffers=1;
+ props.cbBuffer=this->m_sOurType.lSampleSize;
+ props.cbAlign=props.cbPrefix=0;
+ this->m_pDS_Filter->m_pAll->vt->SetProperties(this->m_pDS_Filter->m_pAll, &props, &props1);
+ this->m_pDS_Filter->m_pAll->vt->Commit(this->m_pDS_Filter->m_pAll);
+ }
+ /*
+ catch (FatalError& e)
+ {
+ e.PrintAll();
+ delete[] m_sVhdr;
+ delete[] m_sVhdr2;
+ delete m_pDS_Filter;
+ throw;
+ }
+ */
+ return this;
+}
+
+void DS_AudioDecoder_Destroy(DS_AudioDecoder *this)
+{
+ free(this->m_sVhdr);
+ free(this->m_sVhdr2);
+ DS_Filter_Destroy(this->m_pDS_Filter);
+ free(this);
+}
+
+int DS_AudioDecoder_Convert(DS_AudioDecoder *this, const void* in_data, uint_t in_size,
+ void* out_data, uint_t out_size,
+ uint_t* size_read, uint_t* size_written)
+{
+ uint_t written = 0;
+ uint_t read = 0;
+
+ if (!in_data || !out_data)
+ return -1;
+
+ in_size -= in_size%this->in_fmt.nBlockAlign;
+ while (in_size>0)
+ {
+ uint_t frame_size = 0;
+ char* frame_pointer;
+ IMediaSample* sample=0;
+ char* ptr;
+ int result;
+
+// this->m_pOurOutput->SetFramePointer(out_data+written);
+ COutputPin_SetFramePointer(this->m_pDS_Filter->m_pOurOutput,&frame_pointer);
+ COutputPin_SetFrameSizePointer(this->m_pDS_Filter->m_pOurOutput,(long*)&frame_size);
+ this->m_pDS_Filter->m_pAll->vt->GetBuffer(this->m_pDS_Filter->m_pAll, &sample, 0, 0, 0);
+ if (!sample)
+ {
+ Debug printf("DS_AudioDecoder::Convert() Error: null sample\n");
+ break;
+ }
+ sample->vt->GetPointer(sample, (BYTE **)&ptr);
+ memcpy(ptr, (const uint8_t*)in_data + read, this->in_fmt.nBlockAlign);
+ sample->vt->SetActualDataLength(sample, this->in_fmt.nBlockAlign);
+ sample->vt->SetSyncPoint(sample, 1);
+ sample->vt->SetPreroll(sample, 0);
+ result = this->m_pDS_Filter->m_pImp->vt->Receive(this->m_pDS_Filter->m_pImp, sample);
+ if (result)
+ Debug printf("DS_AudioDecoder::Convert() Error: putting data into input pin %x\n", result);
+ if ((written + frame_size) > out_size)
+ {
+ sample->vt->Release((IUnknown*)sample);
+ break;
+ }
+ memcpy((uint8_t*)out_data + written, frame_pointer, frame_size);
+ sample->vt->Release((IUnknown*)sample);
+ read+=this->in_fmt.nBlockAlign;
+ written+=frame_size;
+ }
+ if (size_read)
+ *size_read = read;
+ if (size_written)
+ *size_written = written;
+ return 0;
+}
+
+int DS_AudioDecoder_GetSrcSize(DS_AudioDecoder *this, int dest_size)
+{
+ double efficiency;
+ int frames;
+
+ efficiency = (double) this->in_fmt.nAvgBytesPerSec
+ / (this->in_fmt.nSamplesPerSec*this->in_fmt.nBlockAlign);
+ frames = (int)(dest_size*efficiency);
+ if (frames < 1)
+ frames = 1;
+ return frames * this->in_fmt.nBlockAlign;
+}
diff --git a/src/libw32dll/DirectShow/DS_AudioDecoder.h b/src/libw32dll/DirectShow/DS_AudioDecoder.h
new file mode 100644
index 000000000..b0d01c4c8
--- /dev/null
+++ b/src/libw32dll/DirectShow/DS_AudioDecoder.h
@@ -0,0 +1,36 @@
+#ifndef AVIFILE_DS_AUDIODECODER_H
+#define AVIFILE_DS_AUDIODECODER_H
+
+#ifndef NOAVIFILE_HEADERS
+#include "audiodecoder.h"
+#include "except.h"
+#else
+#include "../libwin32.h"
+#endif
+#include "DS_Filter.h"
+
+typedef struct _DS_AudioDecoder
+{
+ WAVEFORMATEX in_fmt;
+ AM_MEDIA_TYPE m_sOurType, m_sDestType;
+ DS_Filter* m_pDS_Filter;
+ char* m_sVhdr;
+ char* m_sVhdr2;
+}DS_AudioDecoder;
+
+#ifndef uint_t
+#define uint_t int
+#endif
+
+DS_AudioDecoder * DS_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf);
+
+void DS_AudioDecoder_Destroy(DS_AudioDecoder *this);
+
+int DS_AudioDecoder_Convert(DS_AudioDecoder *this, const void* in_data, uint_t in_size,
+ void* out_data, uint_t out_size,
+ uint_t* size_read, uint_t* size_written);
+
+int DS_AudioDecoder_GetSrcSize(DS_AudioDecoder *this, int dest_size);
+
+
+#endif // AVIFILE_DS_AUDIODECODER_H
diff --git a/src/libw32dll/DirectShow/DS_Filter.c b/src/libw32dll/DirectShow/DS_Filter.c
new file mode 100644
index 000000000..95adb3ccc
--- /dev/null
+++ b/src/libw32dll/DirectShow/DS_Filter.c
@@ -0,0 +1,237 @@
+#include "DS_Filter.h"
+#include "../wine/driver.h"
+
+#define NOAVIFILE_HEADERS
+
+#ifndef NOAVIFILE_HEADERS
+#include "except.h"
+#else
+#include "../libwin32.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define __MODULE__ "DirectShow generic filter"
+
+typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**);
+
+#define FATAL printf
+
+//extern "C" int STDCALL LoadLibraryA(const char*);
+//extern "C" STDCALL void* GetProcAddress(int, const char*); // STDCALL has to be first NetBSD
+//extern "C" int STDCALL FreeLibrary(int);
+
+void DS_Filter_Destroy(DS_Filter * this)
+{
+ DS_Filter_Stop(this);
+
+ if (this->m_iState == 0)
+ return;
+ this->m_iState = 0;
+
+ if (this->m_pOurInput)
+ this->m_pOurInput->vt->Release((IUnknown*)this->m_pOurInput);
+ if (this->m_pInputPin)
+ this->m_pInputPin->vt->Disconnect(this->m_pInputPin);
+ if (this->m_pOutputPin)
+ this->m_pOutputPin->vt->Disconnect(this->m_pOutputPin);
+ if (this->m_pFilter)
+ this->m_pFilter->vt->Release((IUnknown*)this->m_pFilter);
+ if (this->m_pOutputPin)
+ this->m_pOutputPin->vt->Release((IUnknown*)this->m_pOutputPin);
+ if (this->m_pInputPin)
+ this->m_pInputPin->vt->Release((IUnknown*)this->m_pInputPin);
+ if (this->m_pImp)
+ this->m_pImp->vt->Release((IUnknown*)this->m_pImp);
+
+ COutputPin_Destroy(this->m_pOurOutput);
+ CBaseFilter2_Destroy(this->m_pParentFilter);
+ CBaseFilter_Destroy(this->m_pSrcFilter);
+
+ // FIXME - we are still leaving few things allocated!
+ if (this->m_iHandle)
+ FreeLibrary(this->m_iHandle);
+
+ CodecRelease();
+}
+
+DS_Filter * DS_Filter_Create(const char* dllname, const GUID* id,
+ AM_MEDIA_TYPE* in_fmt,
+ AM_MEDIA_TYPE* out_fmt)
+{
+ DS_Filter *this;
+ this = malloc(sizeof(DS_Filter));
+
+ this->m_iHandle = 0;
+ this->m_pFilter = 0;
+ this->m_pInputPin = 0;
+ this->m_pOutputPin = 0;
+ this->m_pSrcFilter = 0;
+ this->m_pParentFilter = 0;
+ this->m_pOurInput = 0;
+ this->m_pOurOutput = 0;
+ this->m_pAll = 0;
+ this->m_pImp = 0;
+ this->m_iState = 0;
+ CodecAlloc();
+
+ /* __asm__ __volatile__(
+ "int $0x3\n" : :
+ );*/
+
+
+ /*try*/
+ {
+ GETCLASS func;
+ HRESULT result;
+ struct IClassFactory* factory = 0;
+ struct IUnknown* object = 0;
+ IEnumPins* enum_pins = 0;
+ IPin* array[256];
+ ULONG fetched;
+ unsigned int i;
+
+ this->m_iHandle = LoadLibraryA(dllname);
+ if (!this->m_iHandle)
+ FATAL("Could not open DirectShow DLL: %.200s", dllname);
+
+ func = (GETCLASS)GetProcAddress(this->m_iHandle, "DllGetClassObject");
+ if (!func)
+ FATAL("Illegal or corrupt DirectShow DLL: %.200s", dllname);
+
+ result = func(id, &IID_IClassFactory, (void**)&factory);
+ if (result || !factory)
+ FATAL("No such class object");
+
+ result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object);
+ factory->vt->Release((IUnknown*)factory);
+ if (result || !object)
+ FATAL("Class factory failure");
+
+ result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&this->m_pFilter);
+ object->vt->Release((IUnknown*)object);
+ if (result || !this->m_pFilter)
+ FATAL("Object does not have IBaseFilter interface");
+
+ // enumerate pins
+ result = this->m_pFilter->vt->EnumPins(this->m_pFilter, &enum_pins);
+ if (result || !enum_pins)
+ FATAL("Could not enumerate pins");
+
+ enum_pins->vt->Reset(enum_pins);
+ result = enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched);
+ Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result);
+
+ for (i = 0; i < fetched; i++)
+ {
+ int direction = -1;
+ array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction);
+ if (!this->m_pInputPin && direction == 0)
+ {
+ this->m_pInputPin = array[i];
+ this->m_pInputPin->vt->AddRef((IUnknown*)this->m_pInputPin);
+ }
+ if (!this->m_pOutputPin && direction == 1)
+ {
+ this->m_pOutputPin = array[i];
+ this->m_pOutputPin->vt->AddRef((IUnknown*)this->m_pOutputPin);
+ }
+ array[i]->vt->Release((IUnknown*)(array[i]));
+ }
+ if (!this->m_pInputPin)
+ FATAL("Input pin not found");
+ if (!this->m_pOutputPin)
+ FATAL("Output pin not found");
+
+ result = this->m_pInputPin->vt->QueryInterface((IUnknown*)this->m_pInputPin,
+ &IID_IMemInputPin,
+ (void**)&this->m_pImp);
+ if (result)
+ FATAL("Error getting IMemInputPin interface");
+ this->m_pOurType = in_fmt;
+ this->m_pDestType = out_fmt;
+ result = this->m_pInputPin->vt->QueryAccept(this->m_pInputPin, this->m_pOurType);
+ if (result)
+ FATAL("Source format is not accepted");
+
+ this->m_pParentFilter = CBaseFilter2_Create();
+ this->m_pSrcFilter = CBaseFilter_Create(this->m_pOurType, this->m_pParentFilter);
+ this->m_pOurInput = CBaseFilter_GetPin(this->m_pSrcFilter);
+ this->m_pOurInput->vt->AddRef((IUnknown*)this->m_pOurInput);
+
+ result = this->m_pInputPin->vt->ReceiveConnection(this->m_pInputPin,
+ this->m_pOurInput,
+ this->m_pOurType);
+ if (result)
+ FATAL("Error connecting to input pin");
+
+ this->m_pOurOutput = COutputPin_Create(this->m_pDestType);
+
+ //extern void trapbug();
+ //trapbug();
+ result = this->m_pOutputPin->vt->ReceiveConnection(this->m_pOutputPin,
+ (IPin*)this->m_pOurOutput,
+ this->m_pDestType);
+ if (result)
+ {
+ //printf("Tracking ACELP %d 0%x\n", result);
+ FATAL("Error connecting to output pin");
+ }
+
+ printf("Using DirectShow codec: %s\n", dllname);
+ this->m_iState = 1;
+ }
+ /*
+ catch (FatalError& e)
+ {
+ //e.PrintAll();
+ destroy();
+ throw;
+ }
+ */
+ return this;
+}
+
+void DS_Filter_Start(DS_Filter *this)
+{
+ HRESULT hr;
+ if (this->m_iState != 1)
+ return;
+
+ Debug printf("DS_Filter::Start() %p\n", this->m_pFilter);
+ hr=this->m_pFilter->vt->Run(this->m_pFilter, 0);
+ if (hr != 0)
+ {
+ Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr);
+ }
+ hr = this->m_pImp->vt->GetAllocator(this->m_pImp, &this->m_pAll);
+ if (hr)
+ {
+ Debug printf("WARNING: error getting IMemAllocator interface %x\n", (int)hr);
+ this->m_pImp->vt->Release((IUnknown*)this->m_pImp);
+ return;
+ }
+ this->m_pImp->vt->NotifyAllocator(this->m_pImp, this->m_pAll, 0);
+ this->m_iState = 2;
+}
+
+void DS_Filter_Stop(DS_Filter *this)
+{
+ if (this->m_iState == 2)
+ {
+ this->m_iState = 1;
+ Debug printf("DS_Filter::Stop() %p\n", this->m_pFilter);
+ if (this->m_pFilter)
+ {
+ //printf("vt: %p\n", this->m_pFilter->vt);
+ //printf("vtstop %p\n", this->m_pFilter->vt->Stop);
+ this->m_pFilter->vt->Stop(this->m_pFilter); // causes weird crash ??? FIXME
+ }
+ else
+ printf("WARNING: DS_Filter::Stop() m_pFilter is NULL!\n");
+ this->m_pAll->vt->Release((IUnknown*)this->m_pAll);
+ this->m_pAll = 0;
+ }
+}
diff --git a/src/libw32dll/DirectShow/DS_Filter.h b/src/libw32dll/DirectShow/DS_Filter.h
new file mode 100644
index 000000000..3b069cffe
--- /dev/null
+++ b/src/libw32dll/DirectShow/DS_Filter.h
@@ -0,0 +1,42 @@
+#ifndef DS_FILTER_H
+#define DS_FILTER_H
+
+#include "inputpin.h"
+#include "outputpin.h"
+
+/**
+ User will allocate and fill format structures, call Create(),
+ and then set up m_pAll.
+ **/
+typedef struct _DS_Filter DS_Filter;
+
+struct _DS_Filter
+{
+ 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;
+ AM_MEDIA_TYPE *m_pDestType;
+ IMemAllocator* m_pAll;
+ IMemInputPin* m_pImp;
+ int m_iState;
+};
+
+void DS_Filter_Destroy(DS_Filter * this);
+
+DS_Filter * DS_Filter_Create(const char* dllname, const GUID* id,
+ AM_MEDIA_TYPE* in_fmt,
+ AM_MEDIA_TYPE* out_fmt);
+
+void DS_Filter_Start(DS_Filter *this);
+
+void DS_Filter_Stop(DS_Filter *this);
+
+#endif /* DS_FILTER_H */
diff --git a/src/libw32dll/DirectShow/Makefile.am b/src/libw32dll/DirectShow/Makefile.am
new file mode 100644
index 000000000..dab35bb05
--- /dev/null
+++ b/src/libw32dll/DirectShow/Makefile.am
@@ -0,0 +1,36 @@
+
+noinst_LTLIBRARIES = libds_filter.la
+
+noinst_HEADERS = DS_Filter.h allocator.h cmediasample.h \
+ guids.h inputpin.h interfaces.h iunk.h outputpin.h \
+ DS_AudioDecoder.h
+
+libds_filter_la_SOURCES = guids.c inputpin.c outputpin.c allocator.c \
+ cmediasample.c DS_Filter.c DS_AudioDecoder.c
+
+##
+##
+CFLAGS = @GLOBAL_CFLAGS@ @X_CFLAGS@ -fno-omit-frame-pointer \
+ -Wmissing-prototypes -Wimplicit-function-declaration \
+ -DWIN32_PATH=\"@w32_path@\"
+
+DEBUG_CFLAGS = @DEBUG_CFLAGS@ @X_CFLAGS@ -fno-omit-frame-pointer \
+ -Wmissing-prototypes -Wimplicit-function-declaration \
+ -DWIN32_PATH=\\\"@w32_path@\\\"
+
+if HAVE_W32DLL
+ds_filter_lib = libds_filter.la
+endif
+
+
+debug:
+ @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
+
diff --git a/src/libw32dll/DirectShow/allocator.c b/src/libw32dll/DirectShow/allocator.c
new file mode 100644
index 000000000..f9f6826ea
--- /dev/null
+++ b/src/libw32dll/DirectShow/allocator.c
@@ -0,0 +1,307 @@
+#include "allocator.h"
+#include "cmediasample.h"
+#include "../wine/com.h"
+#include "../wine/winerror.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+//#undef Debug
+//#define Debug
+
+/*
+class AllocatorKeeper
+{
+public:
+ AllocatorKeeper()
+ {
+ RegisterComClass(&CLSID_MemoryAllocator, MemAllocator::CreateAllocator);
+ }
+ ~AllocatorKeeper()
+ {
+ UnregisterComClass(&CLSID_MemoryAllocator, MemAllocator::CreateAllocator);
+ }
+};
+static AllocatorKeeper keeper;
+*/
+static int Allocator_Used;
+
+void CMediaSample_vector_copy(CMediaSample_vector *this, CMediaSample** in, int sz, int alloc)
+{
+ int i;
+ this->m_Type = malloc(alloc*sizeof(CMediaSample *));
+ this->m_uiSize = sz;
+ this->m_uiAlloc = alloc;
+ for (i = 0; i < sz; i++)
+ this->m_Type[i] = in[i];
+}
+
+CMediaSample** CMediaSample_vector_begin(CMediaSample_vector *this)
+{ return this->m_Type; }
+
+CMediaSample** CMediaSample_vector_end(CMediaSample_vector *this)
+{ return this->m_Type + this->m_uiSize; }
+
+void CMediaSample_vector_pop_back(CMediaSample_vector *this)
+{
+ this->m_uiSize--;
+ if ((this->m_uiAlloc >= 8) && (this->m_uiSize < this->m_uiAlloc / 4))
+ {
+ CMediaSample** t = this->m_Type;
+ CMediaSample_vector_copy(this, this->m_Type, this->m_uiSize, this->m_uiAlloc / 2);
+ free(t);
+ }
+}
+
+void CMediaSample_vector_erase(CMediaSample_vector *this, CMediaSample** pos)
+{
+ if (this->m_uiSize > 0)
+ {
+ while (pos < CMediaSample_vector_end(this) - 1)
+ {
+ pos[0] = pos[1];
+ pos++;
+ }
+ CMediaSample_vector_pop_back(this);
+ }
+}
+
+void CMediaSample_vector_push_back(CMediaSample_vector *this, CMediaSample *m)
+{
+ if (this->m_uiSize + 1 >= this->m_uiAlloc)
+ {
+ CMediaSample** t = this->m_Type;
+ CMediaSample_vector_copy(this, this->m_Type, this->m_uiSize, this->m_uiAlloc * 2);
+ free(t);
+ }
+ this->m_Type[this->m_uiSize++] = m;
+}
+
+
+int CMediaSample_vector_size(CMediaSample_vector *this)
+{ return this->m_uiSize; }
+
+void CMediaSample_vector_clear(CMediaSample_vector *this)
+{
+ if (this->m_uiAlloc > 4)
+ {
+ free( this->m_Type );
+ this->m_uiAlloc = 4;
+ this->m_Type = malloc(this->m_uiAlloc*sizeof(CMediaSample *));
+ }
+ this->m_uiSize = 0;
+}
+
+CMediaSample_vector * CMediaSample_vector_create()
+{
+ CMediaSample_vector *this;
+ this = malloc( sizeof( CMediaSample_vector ) );
+ this->m_uiAlloc = 4;
+ this->m_Type = malloc(sizeof(CMediaSample *) * this->m_uiAlloc);
+ this->m_uiSize = 0;
+ return this;
+}
+
+
+IMPLEMENT_IUNKNOWN(MemAllocator)
+
+long MemAllocator_CreateAllocator(GUID* clsid, GUID* iid, void** ppv)
+{
+ MemAllocator* p;
+ int result;
+
+ if (!ppv) return -1;
+ *ppv = 0;
+ if (memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID)))
+ return -1;
+
+ p = MemAllocator_Create();
+ result=p->vt->QueryInterface((IUnknown*)p, iid, ppv);
+ p->vt->Release((IUnknown*)p);
+ return result;
+}
+
+void MemAllocator_SetPointer(MemAllocator*this, char* pointer)
+{ this->new_pointer=pointer; }
+
+void MemAllocator_ResetPointer(MemAllocator*this)
+{
+ if (this->modified_sample)
+ {
+ this->modified_sample->ResetPointer(this->modified_sample);
+ this->modified_sample=0;
+ }
+}
+
+
+void AllocatorKeeper_Create() {
+RegisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator);
+}
+
+void AllocatorKeeper_Destroy() {
+UnregisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator);
+}
+
+
+static HRESULT STDCALL MemAllocator_SetProperties(IMemAllocator * This,
+ /* [in] */ ALLOCATOR_PROPERTIES *pRequest,
+ /* [out] */ ALLOCATOR_PROPERTIES *pActual)
+{
+ MemAllocator* me = (MemAllocator*)This;
+
+ Debug printf("MemAllocator_SetProperties() called\n");
+ if (!pRequest || !pActual)
+ return E_INVALIDARG;
+ if (pRequest->cBuffers<=0 || pRequest->cbBuffer<=0)
+ return E_FAIL;
+
+ if (CMediaSample_vector_size(me->used_list) || CMediaSample_vector_size(me->free_list))
+ return E_FAIL;
+ me->props = *pRequest;
+ *pActual = *pRequest;
+ return 0;
+}
+
+static HRESULT STDCALL MemAllocator_GetProperties(IMemAllocator * This,
+ /* [out] */ ALLOCATOR_PROPERTIES *pProps)
+{
+ Debug printf("MemAllocator_GetProperties(%p) called\n", This);
+ if (!pProps)
+ return E_INVALIDARG;
+ if (((MemAllocator*)This)->props.cbBuffer<0)
+ return E_FAIL;
+ *pProps=((MemAllocator*)This)->props;
+ return 0;
+}
+
+static HRESULT STDCALL MemAllocator_Commit(IMemAllocator * This)
+{
+ int i;
+ MemAllocator* me = (MemAllocator*)This;
+
+ Debug printf("MemAllocator_Commit(%p) called\n", This);
+ if (((MemAllocator*)This)->props.cbBuffer < 0)
+ return E_FAIL;
+ if (CMediaSample_vector_size(me->used_list) || CMediaSample_vector_size(me->free_list))
+ return E_INVALIDARG;
+ for(i = 0; i<me->props.cBuffers; i++)
+ CMediaSample_vector_push_back(me->free_list,CMediaSample_Create(This, me->props.cbBuffer));
+
+ //printf("Added mem %p: %d %d size: %d\n", me, me->free_list.size(), me->props.cBuffers, me->props.cbBuffer);
+ return 0;
+}
+
+static HRESULT STDCALL MemAllocator_Decommit(IMemAllocator * This)
+{
+ MemAllocator* me=(MemAllocator*)This;
+ CMediaSample **it;
+ Debug printf("MemAllocator_Decommit(%p) called\n", This);
+
+ //printf("Deleted mem %p: %d %d\n", me, me->free_list.size(), me->used_list.size());
+ for(it=CMediaSample_vector_begin(me->free_list); it!=CMediaSample_vector_end(me->free_list); it++)
+ CMediaSample_Destroy(*it);
+ for(it=CMediaSample_vector_begin(me->used_list); it!=CMediaSample_vector_end(me->used_list); it++)
+ CMediaSample_Destroy(*it);
+
+ CMediaSample_vector_clear(me->free_list);
+ CMediaSample_vector_clear(me->used_list);
+ return 0;
+}
+
+static HRESULT STDCALL MemAllocator_GetBuffer(IMemAllocator * This,
+ /* [out] */ IMediaSample **ppBuffer,
+ /* [in] */ REFERENCE_TIME *pStartTime,
+ /* [in] */ REFERENCE_TIME *pEndTime,
+ /* [in] */ DWORD dwFlags)
+{
+ MemAllocator* me = (MemAllocator*)This;
+ CMediaSample **it;
+
+ it = CMediaSample_vector_begin(me->free_list);
+
+ Debug printf("MemAllocator_GetBuffer(%p) called\n", This);
+ if (CMediaSample_vector_size(me->free_list) == 0)
+ {
+ Debug printf("No samples available\n");
+ return E_FAIL;//should block here if no samples are available
+ }
+ CMediaSample_vector_push_back(me->used_list,*it);
+ *ppBuffer = (IMediaSample *)*it;
+ (*ppBuffer)->vt->AddRef((IUnknown*)*ppBuffer);
+ if (me->new_pointer)
+ {
+ if(me->modified_sample)
+ me->modified_sample->ResetPointer(me->modified_sample);
+ (*it)->SetPointer(*it,me->new_pointer);
+ me->modified_sample = *it;
+ me->new_pointer = 0;
+ }
+ CMediaSample_vector_erase(me->free_list,it);
+ return 0;
+}
+
+static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator * This,
+ /* [in] */ IMediaSample *pBuffer)
+{
+ MemAllocator* me = (MemAllocator*)This;
+ CMediaSample **it;
+
+ Debug printf("MemAllocator_ReleaseBuffer(%p) called\n", This);
+
+ for (it = CMediaSample_vector_begin(me->used_list); it != CMediaSample_vector_end(me->used_list); it++)
+ if ( *it == (CMediaSample*)pBuffer)
+ {
+ CMediaSample_vector_erase(me->used_list,it);
+ CMediaSample_vector_push_back(me->free_list,(CMediaSample*)pBuffer);
+ return 0;
+ }
+ Debug printf("Releasing unknown buffer\n");
+ return E_FAIL;
+}
+
+MemAllocator * MemAllocator_Create()
+{
+ MemAllocator *this;
+
+ this = malloc(sizeof(MemAllocator));
+
+ Debug printf("MemAllocator::MemAllocator() called\n");
+ this->vt = malloc(sizeof(IMemAllocator_vt));
+
+ this->vt->QueryInterface = MemAllocator_QueryInterface;
+ this->vt->AddRef = MemAllocator_AddRef;
+ this->vt->Release = MemAllocator_Release;
+ this->vt->SetProperties = MemAllocator_SetProperties;
+ this->vt->GetProperties = MemAllocator_GetProperties;
+ this->vt->Commit = MemAllocator_Commit;
+ this->vt->Decommit = MemAllocator_Decommit;
+ this->vt->GetBuffer = MemAllocator_GetBuffer;
+ this->vt->ReleaseBuffer = MemAllocator_ReleaseBuffer;
+
+ this->refcount = 1;
+ this->props.cBuffers = 1;
+ this->props.cbBuffer = 65536; /* :/ */
+ this->props.cbAlign = this->props.cbPrefix = 0;
+
+ this->new_pointer=0;
+ this->modified_sample=0;
+
+ this->interfaces[0]=IID_IUnknown;
+ this->interfaces[1]=IID_IMemAllocator;
+
+ this->used_list = CMediaSample_vector_create();
+ this->free_list = CMediaSample_vector_create();
+
+ if( Allocator_Used++ == 0)
+ RegisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator);
+
+ return this;
+}
+
+void MemAllocator_Destroy(MemAllocator *this)
+{
+ if( --Allocator_Used == 0)
+ UnregisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator);
+
+ Debug printf("MemAllocator::~MemAllocator() called\n");
+ free( this->vt );
+}
diff --git a/src/libw32dll/DirectShow/allocator.h b/src/libw32dll/DirectShow/allocator.h
new file mode 100644
index 000000000..1d37dd920
--- /dev/null
+++ b/src/libw32dll/DirectShow/allocator.h
@@ -0,0 +1,51 @@
+#ifndef DS_ALLOCATOR_H
+#define DS_ALLOCATOR_H
+
+/*
+#ifndef NOAVIFILE_HEADERS
+#include "default.h"
+#else
+#include "../wine/libwin32.h"
+#endif
+*/
+
+#include "interfaces.h"
+#include "cmediasample.h"
+#include "iunk.h"
+
+typedef struct _CMediaSample_vector
+{
+ CMediaSample** m_Type;
+ int m_uiSize;
+ int m_uiAlloc;
+} CMediaSample_vector;
+
+typedef struct _MemAllocator
+{
+ IMemAllocator_vt *vt;
+
+ ALLOCATOR_PROPERTIES props;
+
+ CMediaSample_vector * used_list;
+ CMediaSample_vector * free_list;
+
+ char* new_pointer;
+ CMediaSample* modified_sample;
+ GUID interfaces[2];
+ DECLARE_IUNKNOWN(MemAllocator);
+
+ /*
+ MemAllocator();
+ ~MemAllocator();
+ static long CreateAllocator(GUID* clsid, GUID* iid, void** ppv);
+ */
+} MemAllocator;
+
+MemAllocator * MemAllocator_Create();
+void MemAllocator_Destroy(MemAllocator *this);
+
+long MemAllocator_CreateAllocator(GUID* clsid, GUID* iid, void** ppv);
+void MemAllocator_SetPointer(MemAllocator*this, char* pointer);
+void MemAllocator_ResetPointer(MemAllocator*this);
+
+#endif /* DS_ALLOCATOR_H */
diff --git a/src/libw32dll/DirectShow/cmediasample.c b/src/libw32dll/DirectShow/cmediasample.c
new file mode 100644
index 000000000..1f2f2d0ca
--- /dev/null
+++ b/src/libw32dll/DirectShow/cmediasample.c
@@ -0,0 +1,263 @@
+#include "cmediasample.h"
+#include "../wine/winerror.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static long STDCALL CMediaSample_QueryInterface(IUnknown * This,
+ /* [in] */ IID* iid,
+ /* [iid_is][out] */ void **ppv)
+{
+ Debug printf("CMediaSample_QueryInterface() called\n");
+ if (!ppv)
+ return E_INVALIDARG;
+ if (!memcmp(iid, &IID_IUnknown, 16))
+ {
+ *ppv=(void*)This;
+ ((IMediaSample *)This)->vt->AddRef(This);
+ return 0;
+ }
+ if (!memcmp(iid, &IID_IMediaSample, 16))
+ {
+ *ppv=(void*)This;
+ ((IMediaSample *)This)->vt->AddRef(This);
+ return 0;
+ }
+ return E_NOINTERFACE;
+}
+
+static long STDCALL CMediaSample_AddRef(IUnknown* This)
+{
+ Debug printf("CMediaSample_AddRef() called\n");
+ ((CMediaSample*)This)->refcount++;
+ return 0;
+}
+
+static long STDCALL CMediaSample_Release(IUnknown* This)
+{
+ CMediaSample* parent=(CMediaSample*)This;
+ Debug printf("%p: CMediaSample_Release() called, new refcount %d\n",
+ This, ((CMediaSample*)This)->refcount-1);
+ if (--((CMediaSample*)This)->refcount==0)
+ parent->all->vt->ReleaseBuffer((IMemAllocator*)(parent->all),
+ (IMediaSample*)This);
+ return 0;
+}
+
+static HRESULT STDCALL CMediaSample_GetPointer(IMediaSample * This,
+ /* [out] */ BYTE **ppBuffer)
+{
+ Debug printf("%p: CMediaSample_GetPointer() called\n", This);
+ if (!ppBuffer)
+ return E_INVALIDARG;
+ *ppBuffer=(BYTE *)((CMediaSample*)This)->block;
+ return 0;
+}
+
+static long STDCALL CMediaSample_GetSize(IMediaSample * This)
+{
+ Debug printf("%p: CMediaSample_GetSize() called -> %d\n",
+ This, ((CMediaSample*)This)->size);
+ return ((CMediaSample*)This)->size;
+}
+
+static HRESULT STDCALL CMediaSample_GetTime(IMediaSample * This,
+ /* [out] */ REFERENCE_TIME *pTimeStart,
+ /* [out] */ REFERENCE_TIME *pTimeEnd)
+{
+ Debug printf("%p: CMediaSample_GetTime() called\n", This);
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL CMediaSample_SetTime(IMediaSample * This,
+ /* [in] */ REFERENCE_TIME *pTimeStart,
+ /* [in] */ REFERENCE_TIME *pTimeEnd)
+{
+ Debug printf("%p: CMediaSample_SetTime() called\n", This);
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL CMediaSample_IsSyncPoint(IMediaSample * This)
+{
+ Debug printf("%p: CMediaSample_IsSyncPoint() called\n", This);
+ if (((CMediaSample*)This)->isSyncPoint)
+ return 0;
+ return 1;
+}
+
+static HRESULT STDCALL CMediaSample_SetSyncPoint(IMediaSample * This,
+ long bIsSyncPoint)
+{
+ Debug printf("%p: CMediaSample_SetSyncPoint() called\n", This);
+ ((CMediaSample*)This)->isSyncPoint=bIsSyncPoint;
+ return 0;
+}
+
+static HRESULT STDCALL CMediaSample_IsPreroll(IMediaSample * This)
+{
+ Debug printf("%p: CMediaSample_IsPreroll() called\n", This);
+
+ if (((CMediaSample*)This)->isPreroll)
+ return 0;//S_OK
+
+ return 1;//S_FALSE
+}
+
+static HRESULT STDCALL CMediaSample_SetPreroll(IMediaSample * This,
+ long bIsPreroll)
+{
+ Debug printf("%p: CMediaSample_SetPreroll() called\n", This);
+ ((CMediaSample*)This)->isPreroll=bIsPreroll;
+ return 0;
+}
+
+static long STDCALL CMediaSample_GetActualDataLength(IMediaSample * This)
+{
+ Debug printf("%p: CMediaSample_GetActualDataLength() called -> %d\n", This, ((CMediaSample*)This)->actual_size);
+ return ((CMediaSample*)This)->actual_size;
+}
+
+static HRESULT STDCALL CMediaSample_SetActualDataLength(IMediaSample * This,
+ long __MIDL_0010)
+{
+ Debug printf("%p: CMediaSample_SetActualDataLength(%ld) called\n", This, __MIDL_0010);
+ if (__MIDL_0010 > ((CMediaSample*)This)->size)
+ {
+ printf("%p: ERROR: CMediaSample buffer overflow\n", This);
+ }
+ ((CMediaSample*)This)->actual_size=__MIDL_0010;
+ return 0;
+}
+
+static HRESULT STDCALL CMediaSample_GetMediaType(IMediaSample * This,
+ AM_MEDIA_TYPE **ppMediaType)
+{
+ AM_MEDIA_TYPE *t=&((CMediaSample*)This)->media_type;
+
+ Debug printf("%p: CMediaSample_GetMediaType() called\n", This);
+ if(!ppMediaType)
+ return E_INVALIDARG;
+ if(!((CMediaSample*)This)->type_valid)
+ {
+ *ppMediaType=0;
+ return 1;
+ }
+// 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;
+}
+
+static HRESULT STDCALL CMediaSample_SetMediaType(IMediaSample * This,
+ AM_MEDIA_TYPE *pMediaType)
+{
+ AM_MEDIA_TYPE *t = &((CMediaSample*)This)->media_type;
+
+ Debug printf("%p: CMediaSample_SetMediaType() called\n", This);
+ if (!pMediaType)
+ return E_INVALIDARG;
+ 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;
+}
+
+static HRESULT STDCALL CMediaSample_IsDiscontinuity(IMediaSample * This)
+{
+ Debug printf("%p: CMediaSample_IsDiscontinuity() called\n", This);
+ return 1;
+}
+
+static HRESULT STDCALL CMediaSample_SetDiscontinuity(IMediaSample * This,
+ long bDiscontinuity)
+{
+ Debug printf("%p: CMediaSample_SetDiscontinuity() called\n", This);
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL CMediaSample_GetMediaTime(IMediaSample * This,
+ /* [out] */ LONGLONG *pTimeStart,
+ /* [out] */ LONGLONG *pTimeEnd)
+{
+ Debug printf("%p: CMediaSample_GetMediaTime() called\n", This);
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL CMediaSample_SetMediaTime(IMediaSample * This,
+ /* [in] */ LONGLONG *pTimeStart,
+ /* [in] */ LONGLONG *pTimeEnd)
+{
+ Debug printf("%p: CMediaSample_SetMediaTime() called\n", This);
+ return E_NOTIMPL;
+}
+
+void CMediaSample_SetPointer(CMediaSample *this, char* pointer)
+{ this->block = pointer; }
+
+void CMediaSample_ResetPointer(CMediaSample *this)
+{ this->block = this->own_block; }
+
+CMediaSample * CMediaSample_Create(IMemAllocator* allocator, long _size)
+{
+ CMediaSample *this;
+
+ this = malloc( sizeof( CMediaSample ) );
+ this->vt = malloc( sizeof( IMediaSample_vt ) );
+
+ this->vt->QueryInterface = CMediaSample_QueryInterface;
+ this->vt->AddRef = CMediaSample_AddRef;
+ this->vt->Release = CMediaSample_Release;
+
+ this->vt->GetPointer = CMediaSample_GetPointer;
+ this->vt->GetSize = CMediaSample_GetSize;
+ this->vt->GetTime = CMediaSample_GetTime;
+ this->vt->SetTime = CMediaSample_SetTime;
+ this->vt->IsSyncPoint = CMediaSample_IsSyncPoint;
+ this->vt->SetSyncPoint = CMediaSample_SetSyncPoint;
+ this->vt->IsPreroll = CMediaSample_IsPreroll;
+ this->vt->SetPreroll = CMediaSample_SetPreroll;
+ this->vt->GetActualDataLength = CMediaSample_GetActualDataLength;
+ this->vt->SetActualDataLength = CMediaSample_SetActualDataLength;
+ this->vt->GetMediaType = CMediaSample_GetMediaType;
+ this->vt->SetMediaType = CMediaSample_SetMediaType;
+ this->vt->IsDiscontinuity = CMediaSample_IsDiscontinuity;
+ this->vt->SetDiscontinuity = CMediaSample_SetDiscontinuity;
+ this->vt->GetMediaTime = CMediaSample_GetMediaTime;
+ this->vt->SetMediaTime = CMediaSample_SetMediaTime;
+
+ this->all = allocator;
+ this->size = _size;
+ this->refcount = 0;
+ this->actual_size = 0;
+ this->media_type.pbFormat = 0;
+ this->isPreroll = 0;
+ this->type_valid = 0;
+ this->own_block = malloc(this->size);
+ this->block = this->own_block;
+
+ this->SetPointer = CMediaSample_SetPointer;
+ this->ResetPointer = CMediaSample_ResetPointer;
+
+ Debug printf("%p: Creating media sample with size %ld, buffer %p\n",
+ this, _size, this->block);
+ return this;
+}
+
+void CMediaSample_Destroy(CMediaSample *this)
+{
+ Debug printf("%p: CMediaSample::~CMediaSample() called\n", this);
+ if (!this->vt)
+ printf("Second delete of CMediaSample()!!\n");
+ free( this->vt );
+ free( this->own_block );
+ if (this->media_type.pbFormat)
+ CoTaskMemFree(this->media_type.pbFormat);
+ free( this );
+}
diff --git a/src/libw32dll/DirectShow/cmediasample.h b/src/libw32dll/DirectShow/cmediasample.h
new file mode 100644
index 000000000..061566cc1
--- /dev/null
+++ b/src/libw32dll/DirectShow/cmediasample.h
@@ -0,0 +1,34 @@
+#ifndef DS_CMEDIASAMPLE_H
+#define DS_CMEDIASAMPLE_H
+
+#include "interfaces.h"
+#include "guids.h"
+
+typedef struct _CMediaSample
+{
+ IMediaSample_vt *vt;
+
+ IMemAllocator* all;
+ int size;
+ int actual_size;
+ char* block;
+ char* own_block;
+ int refcount;
+ int isPreroll;
+ int isSyncPoint;
+ AM_MEDIA_TYPE media_type;
+ int type_valid;
+
+ /*
+ CMediaSample(IMemAllocator* allocator, long _size);
+ ~CMediaSample();
+ */
+
+ void (*SetPointer)(struct _CMediaSample *this, char* pointer);
+ void (*ResetPointer)(struct _CMediaSample *this);
+} CMediaSample;
+
+CMediaSample * CMediaSample_Create(IMemAllocator* allocator, long _size);
+void CMediaSample_Destroy(CMediaSample *this);
+
+#endif /* DS_CMEDIASAMPLE_H */
diff --git a/src/libw32dll/DirectShow/guids.c b/src/libw32dll/DirectShow/guids.c
new file mode 100644
index 000000000..3a8096373
--- /dev/null
+++ b/src/libw32dll/DirectShow/guids.c
@@ -0,0 +1,64 @@
+#include "guids.h"
+int DSHOW_DEBUG=0;
+
+GUID CLSID_DivxDecompressorCF={0x82CCd3E0, 0xF71A, 0x11D0,
+ { 0x9f, 0xe5, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa}};
+GUID IID_IDivxFilterInterface={0xd132ee97, 0x3e38, 0x4030,
+ {0x8b, 0x17, 0x59, 0x16, 0x3b, 0x30, 0xa1, 0xf5}};
+
+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/src/libw32dll/DirectShow/guids.h b/src/libw32dll/DirectShow/guids.h
new file mode 100644
index 000000000..a2525848a
--- /dev/null
+++ b/src/libw32dll/DirectShow/guids.h
@@ -0,0 +1,96 @@
+#ifndef GUIDS_H
+#define GUIDS_H
+
+#include "../wine/com.h"
+#include "../wine/winbase.h"
+#include "../wine/vfw.h"
+
+extern int DSHOW_DEBUG;
+#define Debug if(DSHOW_DEBUG)
+
+typedef void 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 struct _RECT32
+{
+ int left, top, right, bottom;
+}RECT32;
+
+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
+ unsigned long dwBitErrorRate; // Bit error rate for this stream
+ REFERENCE_TIME AvgTimePerFrame; // Average time per frame (100ns units)
+ BITMAPINFOHEADER bmiHeader;
+} VIDEOINFOHEADER;
+
+typedef struct _AllocatorProperties
+{
+ long cBuffers;
+ long cbBuffer;
+ long cbAlign;
+ long cbPrefix;
+} ALLOCATOR_PROPERTIES;
+
+typedef struct _IBaseFilter IBaseFilter;
+
+typedef struct _PinInfo
+{
+ IBaseFilter *pFilter;
+ PIN_DIRECTION dir;
+ unsigned short achName[128];
+} PIN_INFO;
+
+extern GUID IID_IBaseFilter;
+extern GUID IID_IEnumPins;
+extern GUID IID_IEnumMediaTypes;
+extern GUID IID_IMemInputPin;
+extern GUID IID_IMemAllocator;
+extern GUID IID_IMediaSample;
+extern GUID IID_DivxHidden;
+extern GUID IID_Iv50Hidden;
+extern GUID CLSID_DivxDecompressorCF;
+extern GUID IID_IDivxFilterInterface;
+extern GUID CLSID_IV50_Decoder;
+extern GUID CLSID_MemoryAllocator;
+extern GUID MEDIATYPE_Video;
+extern GUID GUID_NULL;
+extern GUID FORMAT_VideoInfo;
+extern GUID MEDIASUBTYPE_RGB565;
+extern GUID MEDIASUBTYPE_RGB555;
+extern GUID MEDIASUBTYPE_RGB24;
+extern GUID MEDIASUBTYPE_RGB32;
+extern GUID MEDIASUBTYPE_YUYV;
+extern GUID MEDIASUBTYPE_IYUV;
+extern GUID MEDIASUBTYPE_YVU9;
+extern GUID MEDIASUBTYPE_Y411;
+extern GUID MEDIASUBTYPE_Y41P;
+extern GUID MEDIASUBTYPE_YUY2;
+extern GUID MEDIASUBTYPE_YVYU;
+extern GUID MEDIASUBTYPE_UYVY;
+extern GUID MEDIASUBTYPE_Y211;
+extern GUID MEDIASUBTYPE_YV12;
+
+#endif
diff --git a/src/libw32dll/DirectShow/inputpin.c b/src/libw32dll/DirectShow/inputpin.c
new file mode 100644
index 000000000..c20c16811
--- /dev/null
+++ b/src/libw32dll/DirectShow/inputpin.c
@@ -0,0 +1,682 @@
+#include "inputpin.h"
+#include "../wine/winerror.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+IMPLEMENT_IUNKNOWN(CInputPin)
+
+IMPLEMENT_IUNKNOWN(CRemotePin)
+
+IMPLEMENT_IUNKNOWN(CRemotePin2)
+
+IMPLEMENT_IUNKNOWN(CBaseFilter)
+
+IMPLEMENT_IUNKNOWN(CBaseFilter2)
+
+typedef struct _CEnumPins
+{
+ struct _IEnumPins_vt *vt;
+ IPin* pin1;
+ IPin* pin2;
+ int counter;
+ GUID interfaces[2];
+ DECLARE_IUNKNOWN(CEnumPins)
+
+} CEnumPins;
+
+long STDCALL CEnumPins_Next(IEnumPins * This,
+ /* [in] */ unsigned long cMediaTypes,
+ /* [size_is][out] */ IPin **ppMediaTypes,
+ /* [out] */ unsigned long *pcFetched)
+{
+ int *lcounter=&((CEnumPins*)This)->counter;
+ IPin* lpin1=((CEnumPins*)This)->pin1;
+ IPin* lpin2=((CEnumPins*)This)->pin2;
+
+ Debug printf("CEnumPins::Next() called\n");
+ if (!ppMediaTypes)
+ return E_INVALIDARG;
+ if (!pcFetched && (cMediaTypes!=1))
+ return E_INVALIDARG;
+ if (cMediaTypes<=0)
+ return 0;
+
+ if (((*lcounter == 2) && lpin2) || ((*lcounter == 1) && !lpin2))
+ {
+ if (pcFetched)
+ *pcFetched=0;
+ return 1;
+ }
+
+ if (pcFetched)
+ *pcFetched=1;
+ if (*lcounter==0)
+ {
+ *ppMediaTypes = lpin1;
+ lpin1->vt->AddRef((IUnknown*)lpin1);
+ }
+ else
+ {
+ *ppMediaTypes = lpin2;
+ lpin2->vt->AddRef((IUnknown*)lpin2);
+ }
+ (*lcounter)++;
+ if (cMediaTypes == 1)
+ return 0;
+ return 1;
+}
+
+long STDCALL CEnumPins_Skip(IEnumPins * This,
+ /* [in] */ unsigned long cMediaTypes)
+{
+ Debug printf("CEnumPins::Skip() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CEnumPins_Reset(IEnumPins * This)
+{
+ Debug printf("CEnumPins::Reset() called\n");
+ ((CEnumPins*)This)->counter=0;
+ return 0;
+}
+
+long STDCALL CEnumPins_Clone(IEnumPins * This,
+ /* [out] */ IEnumPins **ppEnum)
+{
+ Debug printf("CEnumPins::Clone() called\n");
+ return E_NOTIMPL;
+}
+
+void CEnumPins_Destroy(CEnumPins *this)
+{
+ free(this);
+}
+
+IMPLEMENT_IUNKNOWN(CEnumPins)
+
+CEnumPins * CEnumPins_Create(IPin* p, IPin* pp)
+{
+ CEnumPins *this;
+ this = malloc(sizeof(CEnumPins));
+
+ this->vt=malloc(sizeof(IEnumPins_vt));
+
+ this->pin1 = malloc(sizeof(IPin));
+ memcpy(this->pin1,p,sizeof(IPin));
+ this->pin2 = malloc(sizeof(IPin));
+ memcpy(this->pin2,pp,sizeof(IPin));
+ this->counter = 0;
+ this->refcount = 1;
+
+ this->vt->QueryInterface = CEnumPins_QueryInterface;
+ this->vt->AddRef = CEnumPins_AddRef;
+ this->vt->Release = CEnumPins_Release;
+ this->vt->Next = CEnumPins_Next;
+ this->vt->Skip = CEnumPins_Skip;
+ this->vt->Reset = CEnumPins_Reset;
+ this->vt->Clone = CEnumPins_Clone;
+ this->interfaces[0]=IID_IUnknown;
+ this->interfaces[1]=IID_IEnumPins;
+ return this;
+}
+
+
+long STDCALL CInputPin_Connect (
+ IPin * This,
+ /* [in] */ IPin *pReceivePin,
+ /* [in] */ AM_MEDIA_TYPE *pmt)
+{
+ Debug printf("CInputPin::Connect() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CInputPin_ReceiveConnection(IPin * This,
+ /* [in] */ IPin *pConnector,
+ /* [in] */ const AM_MEDIA_TYPE *pmt)
+{
+ Debug printf("CInputPin::ReceiveConnection() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CInputPin_Disconnect(IPin * This)
+{
+ Debug printf("CInputPin::Disconnect() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CInputPin_ConnectedTo(IPin * This, /* [out] */ IPin **pPin)
+{
+ Debug printf("CInputPin::ConnectedTo() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CInputPin_ConnectionMediaType(IPin * This,
+ /* [out] */ AM_MEDIA_TYPE *pmt)
+{
+ Debug printf("CInputPin::ConnectionMediaType() called\n");
+ if(!pmt)return E_INVALIDARG;
+ *pmt=((CInputPin*)This)->type;
+ if(pmt->cbFormat>0)
+ {
+ pmt->pbFormat=(char *)CoTaskMemAlloc(pmt->cbFormat);
+ memcpy(pmt->pbFormat, ((CInputPin*)This)->type.pbFormat, pmt->cbFormat);
+ }
+ return 0;
+}
+
+long STDCALL CInputPin_QueryPinInfo(IPin * This, /* [out] */ PIN_INFO *pInfo)
+{
+ CBaseFilter* lparent=((CInputPin*)This)->parent;
+ Debug printf("CInputPin::QueryPinInfo() called\n");
+ pInfo->dir=PINDIR_OUTPUT;
+ pInfo->pFilter = (IBaseFilter *)lparent;
+ lparent->vt->AddRef((IUnknown*)lparent);
+ pInfo->achName[0]=0;
+ return 0;
+}
+
+long STDCALL CInputPin_QueryDirection(IPin * This,
+ /* [out] */ PIN_DIRECTION *pPinDir)
+{
+ *pPinDir=PINDIR_OUTPUT;
+ Debug printf("CInputPin::QueryDirection() called\n");
+ return 0;
+}
+
+long STDCALL CInputPin_QueryId(IPin * This, /* [out] */ unsigned short* *Id)
+{
+ Debug printf("CInputPin::QueryId() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CInputPin_QueryAccept(IPin * This,
+ /* [in] */ const AM_MEDIA_TYPE *pmt)
+{
+ Debug printf("CInputPin::QueryAccept() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CInputPin_EnumMediaTypes (
+ IPin * This,
+ /* [out] */ IEnumMediaTypes **ppEnum)
+{
+ Debug printf("CInputPin::EnumMediaTypes() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CInputPin_QueryInternalConnections(IPin * This,
+ /* [out] */ IPin **apPin,
+ /* [out][in] */ unsigned long *nPin)
+{
+ Debug printf("CInputPin::QueryInternalConnections() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CInputPin_EndOfStream (IPin * This)
+{
+ Debug printf("CInputPin::EndOfStream() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CInputPin_BeginFlush(IPin * This)
+{
+ Debug printf("CInputPin::BeginFlush() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CInputPin_EndFlush(IPin * This)
+{
+ Debug printf("CInputPin::EndFlush() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CInputPin_NewSegment(IPin * This,
+ /* [in] */ REFERENCE_TIME tStart,
+ /* [in] */ REFERENCE_TIME tStop,
+ /* [in] */ double dRate)
+{
+ Debug printf("CInputPin::NewSegment() called\n");
+ return E_NOTIMPL;
+}
+
+CInputPin * CInputPin_Create(CBaseFilter* p, const AM_MEDIA_TYPE *vh)
+{
+ CInputPin *this;
+ this = malloc(sizeof(CInputPin));
+
+ memcpy(&this->type,vh,sizeof(AM_MEDIA_TYPE));
+ this->refcount = 1;
+ this->parent = p;
+ this->vt=malloc(sizeof(IPin_vt));
+ this->vt->QueryInterface = CInputPin_QueryInterface;
+ this->vt->AddRef = CInputPin_AddRef;
+ this->vt->Release = CInputPin_Release;
+ this->vt->Connect = CInputPin_Connect;
+ this->vt->ReceiveConnection = CInputPin_ReceiveConnection;
+ this->vt->Disconnect=CInputPin_Disconnect;
+ this->vt->ConnectedTo = CInputPin_ConnectedTo;
+ this->vt->ConnectionMediaType = CInputPin_ConnectionMediaType;
+ this->vt->QueryPinInfo = CInputPin_QueryPinInfo;
+ this->vt->QueryDirection = CInputPin_QueryDirection;
+ this->vt->QueryId = CInputPin_QueryId;
+ this->vt->QueryAccept = CInputPin_QueryAccept;
+ this->vt->EnumMediaTypes = CInputPin_EnumMediaTypes;
+ this->vt->QueryInternalConnections = CInputPin_QueryInternalConnections;
+ this->vt->EndOfStream = CInputPin_EndOfStream;
+ this->vt->BeginFlush = CInputPin_BeginFlush;
+ this->vt->EndFlush = CInputPin_EndFlush;
+ this->vt->NewSegment = CInputPin_NewSegment;
+
+ this->interfaces[0]=IID_IUnknown;
+ return this;
+}
+
+void CInputPin_Destroy(CInputPin * this)
+{
+ free(this->vt);
+ free(this);
+}
+
+long STDCALL CBaseFilter_GetClassID(IBaseFilter * This,
+ /* [out] */ CLSID *pClassID)
+{
+ Debug printf("CBaseFilter::GetClassID() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CBaseFilter_Stop(IBaseFilter * This)
+{
+ Debug printf("CBaseFilter::Stop() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CBaseFilter_Pause(IBaseFilter * This)
+{
+ Debug printf("CBaseFilter::Pause() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CBaseFilter_Run(IBaseFilter * This,
+ REFERENCE_TIME tStart)
+{
+ Debug printf("CBaseFilter::Run() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CBaseFilter_GetState(IBaseFilter * This,
+ /* [in] */ unsigned long dwMilliSecsTimeout,
+ // /* [out] */ FILTER_STATE *State)
+ void* State)
+{
+ Debug printf("CBaseFilter::GetState() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CBaseFilter_SetSyncSource(IBaseFilter * This,
+ /* [in] */ IReferenceClock *pClock)
+{
+ Debug printf("CBaseFilter::SetSyncSource() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CBaseFilter_GetSyncSource (
+ IBaseFilter * This,
+ /* [out] */ IReferenceClock **pClock)
+{
+ Debug printf("CBaseFilter::GetSyncSource() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CBaseFilter_EnumPins (
+ IBaseFilter * This,
+ /* [out] */ IEnumPins **ppEnum)
+{
+ Debug printf("CBaseFilter::EnumPins() called\n");
+ *ppEnum=(IEnumPins *)CEnumPins_Create(((CBaseFilter*)This)->pin, ((CBaseFilter*)This)->unused_pin);
+ return 0;
+}
+
+
+long STDCALL CBaseFilter_FindPin (
+ IBaseFilter * This,
+ /* [string][in] */ const unsigned short* Id,
+ /* [out] */ IPin **ppPin)
+{
+ Debug printf("CBaseFilter::FindPin() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CBaseFilter_QueryFilterInfo (
+ IBaseFilter * This,
+// /* [out] */ FILTER_INFO *pInfo)
+ void* pInfo)
+{
+ Debug printf("CBaseFilter::QueryFilterInfo() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CBaseFilter_JoinFilterGraph (
+ IBaseFilter * This,
+ /* [in] */ IFilterGraph *pGraph,
+ /* [string][in] */ const unsigned short* pName)
+{
+ Debug printf("CBaseFilter::JoinFilterGraph() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CBaseFilter_QueryVendorInfo (
+ IBaseFilter * This,
+ /* [string][out] */ unsigned short* *pVendorInfo)
+{
+ Debug printf("CBaseFilter::QueryVendorInfo() called\n");
+ return E_NOTIMPL;
+}
+
+CBaseFilter * CBaseFilter_Create(const AM_MEDIA_TYPE *type, CBaseFilter2* parent)
+{
+ CBaseFilter *this;
+
+ this = malloc(sizeof(CBaseFilter));
+ this->refcount = 1;
+ this->pin=(IPin *)CInputPin_Create(this, type);
+ this->unused_pin=(IPin *)CRemotePin_Create(this, CBaseFilter2_GetPin(parent));
+ this->vt=malloc(sizeof(IBaseFilter_vt));
+ this->vt->QueryInterface = CBaseFilter_QueryInterface;
+ this->vt->AddRef = CBaseFilter_AddRef;
+ this->vt->Release = CBaseFilter_Release;
+ this->vt->GetClassID = CBaseFilter_GetClassID;
+ this->vt->Stop = CBaseFilter_Stop;
+ this->vt->Pause = CBaseFilter_Pause;
+ this->vt->Run = CBaseFilter_Run;
+ this->vt->GetState = CBaseFilter_GetState;
+ this->vt->SetSyncSource = CBaseFilter_SetSyncSource;
+ this->vt->GetSyncSource = CBaseFilter_GetSyncSource;
+ this->vt->EnumPins = CBaseFilter_EnumPins;
+ this->vt->FindPin = CBaseFilter_FindPin;
+ this->vt->QueryFilterInfo = CBaseFilter_QueryFilterInfo;
+ this->vt->JoinFilterGraph = CBaseFilter_JoinFilterGraph;
+ this->vt->QueryVendorInfo = CBaseFilter_QueryVendorInfo;
+ this->interfaces[0]=IID_IUnknown;
+ this->interfaces[1]=IID_IBaseFilter;
+ return this;
+}
+
+
+void CBaseFilter_Destroy(CBaseFilter *this)
+{
+ free(this->vt);
+ this->pin->vt->Release((IUnknown*)this->pin);
+ this->unused_pin->vt->Release((IUnknown*)this->unused_pin);
+ free(this);
+}
+
+IPin* CBaseFilter_GetPin(CBaseFilter *this)
+{return this->pin;}
+
+IPin* CBaseFilter_GetUnusedPin(CBaseFilter *this)
+{return this->unused_pin;}
+
+
+
+long STDCALL CBaseFilter2_GetClassID (
+ IBaseFilter * This,
+ /* [out] */ CLSID *pClassID)
+{
+ Debug printf("CBaseFilter2::GetClassID() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CBaseFilter2_Stop (
+ IBaseFilter * This)
+{
+ Debug printf("CBaseFilter2::Stop() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CBaseFilter2_Pause (IBaseFilter * This)
+{
+ Debug printf("CBaseFilter2::Pause() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CBaseFilter2_Run (IBaseFilter * This, REFERENCE_TIME tStart)
+{
+ Debug printf("CBaseFilter2::Run() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CBaseFilter2_GetState (
+ IBaseFilter * This,
+ /* [in] */ unsigned long dwMilliSecsTimeout,
+// /* [out] */ FILTER_STATE *State)
+ void* State)
+{
+ Debug printf("CBaseFilter2::GetState() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CBaseFilter2_SetSyncSource (
+ IBaseFilter * This,
+ /* [in] */ IReferenceClock *pClock)
+{
+ Debug printf("CBaseFilter2::SetSyncSource() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CBaseFilter2_GetSyncSource (
+ IBaseFilter * This,
+ /* [out] */ IReferenceClock **pClock)
+{
+ Debug printf("CBaseFilter2::GetSyncSource() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CBaseFilter2_EnumPins (
+ IBaseFilter * This,
+ /* [out] */ IEnumPins **ppEnum)
+{
+ Debug printf("CBaseFilter2::EnumPins() called\n");
+ *ppEnum=(IEnumPins *)CEnumPins_Create(((CBaseFilter2*)This)->pin,0);
+ return 0;
+}
+
+
+long STDCALL CBaseFilter2_FindPin (
+ IBaseFilter * This,
+ /* [string][in] */ const unsigned short* Id,
+ /* [out] */ IPin **ppPin)
+{
+ Debug printf("CBaseFilter2::FindPin() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CBaseFilter2_QueryFilterInfo (
+ IBaseFilter * This,
+// /* [out] */ FILTER_INFO *pInfo)
+ void* pInfo)
+{
+ Debug printf("CBaseFilter2::QueryFilterInfo() called\n");
+ return E_NOTIMPL;
+}
+
+
+long STDCALL CBaseFilter2_JoinFilterGraph(IBaseFilter * This,
+ /* [in] */ IFilterGraph *pGraph,
+ /* [string][in] */
+ const unsigned short* pName)
+{
+ Debug printf("CBaseFilter2::JoinFilterGraph() called\n");
+ return E_NOTIMPL;
+}
+
+long STDCALL CBaseFilter2_QueryVendorInfo(IBaseFilter * This,
+ /* [string][out] */
+ unsigned short* *pVendorInfo)
+{
+ Debug printf("CBaseFilter2::QueryVendorInfo() called\n");
+ return E_NOTIMPL;
+}
+
+GUID CBaseFilter2_interf1={0x76c61a30, 0xebe1, 0x11cf, {0x89, 0xf9, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb}};
+GUID CBaseFilter2_interf2={0xaae7e4e2, 0x6388, 0x11d1, {0x8d, 0x93, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2}};
+GUID CBaseFilter2_interf3={0x02ef04dd, 0x7580, 0x11d1, {0xbe, 0xce, 0x00, 0xc0, 0x4f, 0xb6, 0xe9, 0x37}};
+
+CBaseFilter2 * CBaseFilter2_Create()
+{
+ CBaseFilter2 *this;
+
+ this = malloc(sizeof(CBaseFilter2));
+ this->refcount = 1;
+ this->pin=(IPin *)CRemotePin2_Create(this);
+ this->vt=malloc(sizeof(IBaseFilter_vt));
+ memset(this->vt, 0, sizeof (IBaseFilter_vt));
+ this->vt->QueryInterface = CBaseFilter2_QueryInterface;
+ this->vt->AddRef = CBaseFilter2_AddRef;
+ this->vt->Release = CBaseFilter2_Release;
+ this->vt->GetClassID = CBaseFilter2_GetClassID;
+ this->vt->Stop = CBaseFilter2_Stop;
+ this->vt->Pause = CBaseFilter2_Pause;
+ this->vt->Run = CBaseFilter2_Run;
+ this->vt->GetState = CBaseFilter2_GetState;
+ this->vt->SetSyncSource = CBaseFilter2_SetSyncSource;
+ this->vt->GetSyncSource = CBaseFilter2_GetSyncSource;
+ this->vt->EnumPins = CBaseFilter2_EnumPins;
+ this->vt->FindPin = CBaseFilter2_FindPin;
+ this->vt->QueryFilterInfo = CBaseFilter2_QueryFilterInfo;
+ this->vt->JoinFilterGraph = CBaseFilter2_JoinFilterGraph;
+ this->vt->QueryVendorInfo = CBaseFilter2_QueryVendorInfo;
+ this->interfaces[0]=IID_IUnknown;
+ this->interfaces[1]=IID_IBaseFilter;
+ this->interfaces[2]=CBaseFilter2_interf1;
+ this->interfaces[3]=CBaseFilter2_interf2;
+ this->interfaces[4]=CBaseFilter2_interf3;
+
+ return this;
+}
+
+
+
+void CBaseFilter2_Destroy(CBaseFilter2 *this)
+{
+free(this->vt);
+this->pin->vt->Release((IUnknown*)this->pin);
+free(this);
+}
+
+IPin* CBaseFilter2_GetPin(CBaseFilter2 *this)
+{return this->pin;}
+
+static long STDCALL CRemotePin_ConnectedTo(IPin * This, /* [out] */ IPin **pPin)
+{
+ Debug printf("CRemotePin::ConnectedTo called\n");
+ if (!pPin)
+ return E_INVALIDARG;
+ *pPin=((CRemotePin*)This)->remote_pin;
+ (*pPin)->vt->AddRef((IUnknown*)(*pPin));
+ return 0;
+}
+
+static long STDCALL CRemotePin_QueryDirection(IPin * This,
+ /* [out] */ PIN_DIRECTION *pPinDir)
+{
+ Debug printf("CRemotePin::QueryDirection called\n");
+ if (!pPinDir)
+ return E_INVALIDARG;
+ *pPinDir=PINDIR_INPUT;
+ return 0;
+}
+
+static long STDCALL CRemotePin_ConnectionMediaType(IPin* This, /* [out] */ AM_MEDIA_TYPE* pmt)
+{
+ Debug printf("CRemotePin::ConnectionMediaType() called\n");
+ return E_NOTIMPL;
+}
+
+static long STDCALL CRemotePin_QueryPinInfo(IPin* This, /* [out] */ PIN_INFO* pInfo)
+{
+ CBaseFilter* lparent = ((CRemotePin*)This)->parent;
+ Debug printf("CRemotePin::QueryPinInfo() called\n");
+ pInfo->dir=PINDIR_INPUT;
+ pInfo->pFilter = (IBaseFilter *)lparent;
+ lparent->vt->AddRef((IUnknown*)lparent);
+ pInfo->achName[0]=0;
+ return 0;
+}
+
+
+static long STDCALL CRemotePin2_QueryPinInfo(IPin * This,
+ /* [out] */ PIN_INFO *pInfo)
+{
+ CBaseFilter2* lparent=((CRemotePin2*)This)->parent;
+ Debug printf("CRemotePin2::QueryPinInfo called\n");
+ pInfo->pFilter=(IBaseFilter*)lparent;
+ lparent->vt->AddRef((IUnknown*)lparent);
+ pInfo->dir=PINDIR_OUTPUT;
+ pInfo->achName[0]=0;
+ return 0;
+}
+
+CRemotePin * CRemotePin_Create(CBaseFilter* pt, IPin* rpin)
+{
+ CRemotePin *this;
+
+ this = malloc(sizeof(CRemotePin));
+ this->parent = pt;
+ this->remote_pin = rpin;
+ this->refcount = 1;
+ this->vt = malloc(sizeof(IPin_vt));
+ memset(this->vt, 0, sizeof(IPin_vt));
+ this->vt->QueryInterface = CRemotePin_QueryInterface;
+ this->vt->AddRef = CRemotePin_AddRef;
+ this->vt->Release = CRemotePin_Release;
+ this->vt->QueryDirection = CRemotePin_QueryDirection;
+ this->vt->ConnectedTo = CRemotePin_ConnectedTo;
+ this->vt->ConnectionMediaType = CRemotePin_ConnectionMediaType;
+ this->vt->QueryPinInfo = CRemotePin_QueryPinInfo;
+ this->interfaces[0]=IID_IUnknown;
+ return this;
+}
+
+void CRemotePin_Destroy(CRemotePin * this)
+{
+ free(this->vt);
+ free(this);
+}
+
+CRemotePin2 * CRemotePin2_Create(CBaseFilter2* p)
+{
+ CRemotePin2 *this;
+ this = malloc(sizeof(CRemotePin2));
+ this->parent = p,
+ this->refcount = 1;
+ this->vt = malloc(sizeof(IPin_vt));
+ memset(this->vt, 0, sizeof(IPin_vt));
+ this->vt->QueryInterface = CRemotePin2_QueryInterface;
+ this->vt->AddRef = CRemotePin2_AddRef;
+ this->vt->Release = CRemotePin2_Release;
+ this->vt->QueryPinInfo = CRemotePin2_QueryPinInfo;
+ this->interfaces[0]=IID_IUnknown;
+
+ return this;
+}
+
+void CRemotePin2_Destroy(CRemotePin2 * this)
+{
+ free(this->vt);
+ free(this);
+}
diff --git a/src/libw32dll/DirectShow/inputpin.h b/src/libw32dll/DirectShow/inputpin.h
new file mode 100644
index 000000000..ba1e2817e
--- /dev/null
+++ b/src/libw32dll/DirectShow/inputpin.h
@@ -0,0 +1,211 @@
+#ifndef DS_INPUTPIN_H
+#define DS_INPUTPIN_H
+
+#include "interfaces.h"
+
+//class CBaseFilter2;
+
+typedef struct _CBaseFilter
+{
+ struct _IBaseFilter_vt *vt;
+
+ IPin* pin;
+ IPin* unused_pin;
+ GUID interfaces[2];
+ DECLARE_IUNKNOWN(CBaseFilter)
+} CBaseFilter;
+
+typedef struct _CInputPin
+{
+ IPin_vt *vt;
+
+ AM_MEDIA_TYPE type;
+ CBaseFilter* parent;
+ GUID interfaces[1];
+ DECLARE_IUNKNOWN(CInputPin)
+
+} CInputPin;
+
+typedef struct _CBaseFilter2
+{
+ struct _IBaseFilter_vt *vt;
+
+ IPin* pin;
+ GUID interfaces[5];
+ DECLARE_IUNKNOWN(CBaseFilter2)
+
+}CBaseFilter2;
+
+
+typedef struct _CRemotePin
+{
+ IPin_vt *vt;
+ CBaseFilter* parent;
+ IPin* remote_pin;
+ GUID interfaces[1];
+ DECLARE_IUNKNOWN(CRemotePin)
+}CRemotePin;
+
+typedef struct _CRemotePin2
+{
+ IPin_vt *vt;
+ CBaseFilter2* parent;
+ GUID interfaces[1];
+ DECLARE_IUNKNOWN(CRemotePin2)
+}CRemotePin2;
+
+
+long STDCALL CInputPin_Connect (
+ IPin * This,
+ /* [in] */ IPin *pReceivePin,
+ /* [in] */ AM_MEDIA_TYPE *pmt);
+
+long STDCALL CInputPin_ReceiveConnection(IPin * This,
+ /* [in] */ IPin *pConnector,
+ /* [in] */ const AM_MEDIA_TYPE *pmt);
+
+long STDCALL CInputPin_Disconnect(IPin * This);
+long STDCALL CInputPin_ConnectedTo(IPin * This, /* [out] */ IPin **pPin);
+
+long STDCALL CInputPin_ConnectionMediaType(IPin * This,
+ /* [out] */ AM_MEDIA_TYPE *pmt);
+
+long STDCALL CInputPin_QueryPinInfo(IPin * This, /* [out] */ PIN_INFO *pInfo);
+long STDCALL CInputPin_QueryDirection(IPin * This,
+ /* [out] */ PIN_DIRECTION *pPinDir);
+long STDCALL CInputPin_QueryId(IPin * This, /* [out] */ unsigned short* *Id);
+
+long STDCALL CInputPin_QueryAccept(IPin * This,
+ /* [in] */ const AM_MEDIA_TYPE *pmt);
+
+
+long STDCALL CInputPin_EnumMediaTypes (
+ IPin * This,
+ /* [out] */ IEnumMediaTypes **ppEnum);
+
+long STDCALL CInputPin_QueryInternalConnections(IPin * This,
+ /* [out] */ IPin **apPin,
+ /* [out][in] */ unsigned long *nPin);
+
+long STDCALL CInputPin_EndOfStream (IPin * This);
+long STDCALL CInputPin_BeginFlush(IPin * This);
+
+long STDCALL CInputPin_EndFlush(IPin * This);
+
+long STDCALL CInputPin_NewSegment(IPin * This,
+ /* [in] */ REFERENCE_TIME tStart,
+ /* [in] */ REFERENCE_TIME tStop,
+ /* [in] */ double dRate);
+
+CInputPin * CInputPin_Create(CBaseFilter* p, const AM_MEDIA_TYPE *vh);
+void CInputPin_Destroy(CInputPin * this);
+
+long STDCALL CBaseFilter_GetClassID(IBaseFilter * This,
+ /* [out] */ CLSID *pClassID);
+long STDCALL CBaseFilter_Stop(IBaseFilter * This);
+
+long STDCALL CBaseFilter_Pause(IBaseFilter * This);
+
+long STDCALL CBaseFilter_Run(IBaseFilter * This,
+ REFERENCE_TIME tStart);
+
+long STDCALL CBaseFilter_GetState(IBaseFilter * This,
+ /* [in] */ unsigned long dwMilliSecsTimeout,
+ // /* [out] */ FILTER_STATE *State)
+ void* State);
+
+long STDCALL CBaseFilter_SetSyncSource(IBaseFilter * This,
+ /* [in] */ IReferenceClock *pClock);
+
+long STDCALL CBaseFilter_GetSyncSource (
+ IBaseFilter * This,
+ /* [out] */ IReferenceClock **pClock);
+
+
+long STDCALL CBaseFilter_EnumPins (
+ IBaseFilter * This,
+ /* [out] */ IEnumPins **ppEnum);
+
+long STDCALL CBaseFilter_FindPin (
+ IBaseFilter * This,
+ /* [string][in] */ const unsigned short* Id,
+ /* [out] */ IPin **ppPin);
+
+
+long STDCALL CBaseFilter_QueryFilterInfo (
+ IBaseFilter * This,
+// /* [out] */ FILTER_INFO *pInfo)
+ void* pInfo);
+
+long STDCALL CBaseFilter_JoinFilterGraph (
+ IBaseFilter * This,
+ /* [in] */ IFilterGraph *pGraph,
+ /* [string][in] */ const unsigned short* pName);
+
+
+long STDCALL CBaseFilter_QueryVendorInfo (
+ IBaseFilter * This,
+ /* [string][out] */ unsigned short* *pVendorInfo);
+
+CBaseFilter * CBaseFilter_Create(const AM_MEDIA_TYPE *type, CBaseFilter2* parent);
+
+
+void CBaseFilter_Destroy(CBaseFilter *this);
+IPin* CBaseFilter_GetPin(CBaseFilter *this);
+IPin* CBaseFilter_GetUnusedPin(CBaseFilter *this);
+long STDCALL CBaseFilter2_GetClassID (
+ IBaseFilter * This,
+ /* [out] */ CLSID *pClassID);
+
+long STDCALL CBaseFilter2_Stop (
+ IBaseFilter * This);
+long STDCALL CBaseFilter2_Pause (IBaseFilter * This);
+
+long STDCALL CBaseFilter2_Run (IBaseFilter * This, REFERENCE_TIME tStart);
+
+long STDCALL CBaseFilter2_GetState (
+ IBaseFilter * This,
+ /* [in] */ unsigned long dwMilliSecsTimeout,
+// /* [out] */ FILTER_STATE *State)
+ void* State);
+
+long STDCALL CBaseFilter2_SetSyncSource (
+ IBaseFilter * This,
+ /* [in] */ IReferenceClock *pClock);
+long STDCALL CBaseFilter2_GetSyncSource (
+ IBaseFilter * This,
+ /* [out] */ IReferenceClock **pClock);
+
+long STDCALL CBaseFilter2_EnumPins (
+ IBaseFilter * This,
+ /* [out] */ IEnumPins **ppEnum);
+long STDCALL CBaseFilter2_FindPin (
+ IBaseFilter * This,
+ /* [string][in] */ const unsigned short* Id,
+ /* [out] */ IPin **ppPin);
+
+long STDCALL CBaseFilter2_QueryFilterInfo (
+ IBaseFilter * This,
+// /* [out] */ FILTER_INFO *pInfo)
+ void* pInfo);
+
+long STDCALL CBaseFilter2_JoinFilterGraph(IBaseFilter * This,
+ /* [in] */ IFilterGraph *pGraph,
+ /* [string][in] */
+ const unsigned short* pName);
+
+long STDCALL CBaseFilter2_QueryVendorInfo(IBaseFilter * This,
+ /* [string][out] */
+ unsigned short* *pVendorInfo);
+CBaseFilter2 * CBaseFilter2_Create();
+void CBaseFilter2_Destroy(CBaseFilter2 *this);
+
+IPin* CBaseFilter2_GetPin(CBaseFilter2 *this);
+
+CRemotePin * CRemotePin_Create(CBaseFilter* pt, IPin* rpin);
+void CRemotePin_Destroy(CRemotePin * this);
+CRemotePin2 * CRemotePin2_Create(CBaseFilter2* p);
+void CRemotePin2_Destroy(CRemotePin2 * this);
+
+
+#endif /* DS_INPUTPIN_H */
diff --git a/src/libw32dll/DirectShow/interfaces.h b/src/libw32dll/DirectShow/interfaces.h
new file mode 100644
index 000000000..88ef7e4e9
--- /dev/null
+++ b/src/libw32dll/DirectShow/interfaces.h
@@ -0,0 +1,346 @@
+#ifndef DS_INTERFACES_H
+#define DS_INTERFACES_H
+
+/*
+
+Definition of important DirectShow interfaces.
+Created using freely-available DirectX 8.0 SDK
+( http://msdn.microsoft.com )
+
+*/
+
+#include "../wine/com.h"
+#include "guids.h"
+#include "iunk.h"
+
+#ifndef STDCALL
+#define STDCALL __attribute__((__stdcall__))
+#endif
+
+/*typedef GUID& REFIID;*/
+typedef GUID CLSID;
+typedef GUID IID;
+
+/* Sh*t. MSVC++ and g++ use different methods of storing vtables. */
+
+
+/*typedef struct _IBaseFilter IBaseFilter;*/
+typedef struct _IReferenceClock IReferenceClock;
+typedef struct _IEnumPins IEnumPins;
+typedef struct _IEnumMediaTypes IEnumMediaTypes;
+typedef struct _IPin IPin;
+typedef struct _IFilterGraph IFilterGraph;
+typedef struct _IMemInputPin IMemInputPin;
+typedef struct _IMemAllocator IMemAllocator;
+typedef struct _IMediaSample IMediaSample;
+typedef struct _IHidden IHidden;
+typedef struct _IHidden2 IHidden2;
+typedef struct _IDivxFilterInterface IDivxFilterInterface;
+
+typedef struct _IBaseFilter_vt IBaseFilter_vt;
+typedef struct _IReferenceClock_vt IReferenceClock_vt;
+typedef struct _IEnumPins_vt IEnumPins_vt;
+typedef struct _IEnumMediaTypes_vt IEnumMediaTypes_vt;
+typedef struct _IPin_vt IPin_vt;
+typedef struct _IFilterGraph_vt IFilterGraph_vt;
+typedef struct _IMemInputPin_vt IMemInputPin_vt;
+typedef struct _IMemAllocator_vt IMemAllocator_vt;
+typedef struct _IMediaSample_vt IMediaSample_vt;
+typedef struct _IHidden_vt IHidden_vt;
+typedef struct _IHidden2_vt IHidden2_vt;
+typedef struct _IDivxFilterInterface_vt IDivxFilterInterface_vt;
+
+
+enum PIN_DIRECTION;
+
+/*
+class IClassFactory2
+{
+public:
+ virtual long STDCALL QueryInterface(GUID* iid, void** ppv) =0;
+ virtual long STDCALL AddRef(void) =0;
+ virtual long STDCALL Release(void) =0;
+ virtual long STDCALL CreateInstance(IUnknown* pUnkOuter, GUID* riid, void** ppvObject) =0;
+};
+*/
+
+struct _IBaseFilter_vt
+{
+ INHERIT_IUNKNOWN();
+
+ HRESULT STDCALL ( *GetClassID )(IBaseFilter * This,
+ /* [out] */ CLSID *pClassID);
+ HRESULT STDCALL ( *Stop )(IBaseFilter * This);
+ HRESULT STDCALL ( *Pause )(IBaseFilter * This);
+ HRESULT STDCALL ( *Run )(IBaseFilter * This,
+ REFERENCE_TIME tStart);
+ HRESULT STDCALL ( *GetState )(IBaseFilter * This,
+ /* [in] */ unsigned long dwMilliSecsTimeout,
+ ///* [out] */ FILTER_STATE *State);
+ void* State);
+ HRESULT STDCALL ( *SetSyncSource )(IBaseFilter * This,
+ /* [in] */ IReferenceClock *pClock);
+ HRESULT STDCALL ( *GetSyncSource )(IBaseFilter * This,
+ /* [out] */ IReferenceClock **pClock);
+ HRESULT STDCALL ( *EnumPins )(IBaseFilter * This,
+ /* [out] */ IEnumPins **ppEnum);
+ HRESULT STDCALL ( *FindPin )(IBaseFilter * This,
+ /* [string][in] */ const unsigned short* Id,
+ /* [out] */ IPin **ppPin);
+ HRESULT STDCALL ( *QueryFilterInfo )(IBaseFilter * This,
+ // /* [out] */ FILTER_INFO *pInfo);
+ void* pInfo);
+ HRESULT STDCALL ( *JoinFilterGraph )(IBaseFilter * This,
+ /* [in] */ IFilterGraph *pGraph,
+ /* [string][in] */ const unsigned short* pName);
+ HRESULT STDCALL ( *QueryVendorInfo )(IBaseFilter * This,
+ /* [string][out] */ unsigned short* *pVendorInfo);
+};
+
+struct _IBaseFilter
+{
+ struct _IBaseFilter_vt *vt;
+};
+
+
+struct _IEnumPins_vt
+{
+ INHERIT_IUNKNOWN();
+
+ HRESULT STDCALL ( *Next )(IEnumPins * This,
+ /* [in] */ unsigned long cPins,
+ /* [size_is][out] */ IPin **ppPins,
+ /* [out] */ unsigned long *pcFetched);
+ HRESULT STDCALL ( *Skip )(IEnumPins * This,
+ /* [in] */ unsigned long cPins);
+ HRESULT STDCALL ( *Reset )(IEnumPins * This);
+ HRESULT STDCALL ( *Clone )(IEnumPins * This,
+ /* [out] */ IEnumPins **ppEnum);
+};
+
+struct _IEnumPins
+{
+ struct _IEnumPins_vt *vt;
+};
+
+
+struct _IPin_vt
+{
+ INHERIT_IUNKNOWN();
+
+ HRESULT STDCALL ( *Connect )(IPin * This,
+ /* [in] */ IPin *pReceivePin,
+ /* [in] */ /*const*/ AM_MEDIA_TYPE *pmt);
+ HRESULT STDCALL ( *ReceiveConnection )(IPin * This,
+ /* [in] */ IPin *pConnector,
+ /* [in] */ const AM_MEDIA_TYPE *pmt);
+ HRESULT STDCALL ( *Disconnect )(IPin * This);
+ HRESULT STDCALL ( *ConnectedTo )(IPin * This, /* [out] */ IPin **pPin);
+ HRESULT STDCALL ( *ConnectionMediaType )(IPin * This,
+ /* [out] */ AM_MEDIA_TYPE *pmt);
+ HRESULT STDCALL ( *QueryPinInfo )(IPin * This, /* [out] */ PIN_INFO *pInfo);
+ HRESULT STDCALL ( *QueryDirection )(IPin * This,
+ /* [out] */ PIN_DIRECTION *pPinDir);
+ HRESULT STDCALL ( *QueryId )(IPin * This, /* [out] */ unsigned short* *Id);
+ HRESULT STDCALL ( *QueryAccept )(IPin * This,
+ /* [in] */ const AM_MEDIA_TYPE *pmt);
+ HRESULT STDCALL ( *EnumMediaTypes )(IPin * This,
+ /* [out] */ IEnumMediaTypes **ppEnum);
+ HRESULT STDCALL ( *QueryInternalConnections )(IPin * This,
+ /* [out] */ IPin **apPin,
+ /* [out][in] */ unsigned long *nPin);
+ HRESULT STDCALL ( *EndOfStream )(IPin * This);
+ HRESULT STDCALL ( *BeginFlush )(IPin * This);
+ HRESULT STDCALL ( *EndFlush )(IPin * This);
+ HRESULT STDCALL ( *NewSegment )(IPin * This,
+ /* [in] */ REFERENCE_TIME tStart,
+ /* [in] */ REFERENCE_TIME tStop,
+ /* [in] */ double dRate);
+};
+
+struct _IPin
+{
+ IPin_vt *vt;
+};
+
+
+struct _IEnumMediaTypes_vt
+{
+ INHERIT_IUNKNOWN();
+
+ HRESULT STDCALL ( *Next )(IEnumMediaTypes * This,
+ /* [in] */ unsigned long cMediaTypes,
+ /* [size_is][out] */ AM_MEDIA_TYPE **ppMediaTypes,
+ /* [out] */ unsigned long *pcFetched);
+ HRESULT STDCALL ( *Skip )(IEnumMediaTypes * This,
+ /* [in] */ unsigned long cMediaTypes);
+ HRESULT STDCALL ( *Reset )(IEnumMediaTypes * This);
+ HRESULT STDCALL ( *Clone )(IEnumMediaTypes * This,
+ /* [out] */ IEnumMediaTypes **ppEnum);
+};
+
+struct _IEnumMediaTypes
+{
+ IEnumMediaTypes_vt *vt;
+};
+
+
+struct _IMemInputPin_vt
+{
+ INHERIT_IUNKNOWN();
+
+ HRESULT STDCALL ( *GetAllocator )(IMemInputPin * This,
+ /* [out] */ IMemAllocator **ppAllocator);
+ HRESULT STDCALL ( *NotifyAllocator )(IMemInputPin * This,
+ /* [in] */ IMemAllocator *pAllocator,
+ /* [in] */ int bReadOnly);
+ HRESULT STDCALL ( *GetAllocatorRequirements )(IMemInputPin * This,
+ /* [out] */ ALLOCATOR_PROPERTIES *pProps);
+ HRESULT STDCALL ( *Receive )(IMemInputPin * This,
+ /* [in] */ IMediaSample *pSample);
+ HRESULT STDCALL ( *ReceiveMultiple )(IMemInputPin * This,
+ /* [size_is][in] */ IMediaSample **pSamples,
+ /* [in] */ long nSamples,
+ /* [out] */ long *nSamplesProcessed);
+ HRESULT STDCALL ( *ReceiveCanBlock )(IMemInputPin * This);
+};
+
+struct _IMemInputPin
+{
+ IMemInputPin_vt *vt;
+};
+
+
+struct _IMemAllocator_vt
+{
+ INHERIT_IUNKNOWN();
+
+ HRESULT STDCALL ( *SetProperties )(IMemAllocator * This,
+ /* [in] */ ALLOCATOR_PROPERTIES *pRequest,
+ /* [out] */ ALLOCATOR_PROPERTIES *pActual);
+ HRESULT STDCALL ( *GetProperties )(IMemAllocator * This,
+ /* [out] */ ALLOCATOR_PROPERTIES *pProps);
+ HRESULT STDCALL ( *Commit )(IMemAllocator * This);
+ HRESULT STDCALL ( *Decommit )(IMemAllocator * This);
+ HRESULT STDCALL ( *GetBuffer )(IMemAllocator * This,
+ /* [out] */ IMediaSample **ppBuffer,
+ /* [in] */ REFERENCE_TIME *pStartTime,
+ /* [in] */ REFERENCE_TIME *pEndTime,
+ /* [in] */ unsigned long dwFlags);
+ HRESULT STDCALL ( *ReleaseBuffer )(IMemAllocator * This,
+ /* [in] */ IMediaSample *pBuffer);
+};
+
+struct _IMemAllocator
+{
+ IMemAllocator_vt *vt;
+};
+
+
+struct _IMediaSample_vt
+{
+ INHERIT_IUNKNOWN();
+
+ HRESULT STDCALL ( *GetPointer )(IMediaSample * This,
+ /* [out] */ unsigned char **ppBuffer);
+ LONG STDCALL ( *GetSize )(IMediaSample * This);
+ HRESULT STDCALL ( *GetTime )(IMediaSample * This,
+ /* [out] */ REFERENCE_TIME *pTimeStart,
+ /* [out] */ REFERENCE_TIME *pTimeEnd);
+ HRESULT STDCALL ( *SetTime )(IMediaSample * This,
+ /* [in] */ REFERENCE_TIME *pTimeStart,
+ /* [in] */ REFERENCE_TIME *pTimeEnd);
+ HRESULT STDCALL ( *IsSyncPoint )(IMediaSample * This);
+ HRESULT STDCALL ( *SetSyncPoint )(IMediaSample * This,
+ long bIsSyncPoint);
+ HRESULT STDCALL ( *IsPreroll )(IMediaSample * This);
+ HRESULT STDCALL ( *SetPreroll )(IMediaSample * This,
+ long bIsPreroll);
+ LONG STDCALL ( *GetActualDataLength )(IMediaSample * This);
+ HRESULT STDCALL ( *SetActualDataLength )(IMediaSample * This,
+ long __MIDL_0010);
+ HRESULT STDCALL ( *GetMediaType )(IMediaSample * This,
+ AM_MEDIA_TYPE **ppMediaType);
+ HRESULT STDCALL ( *SetMediaType )(IMediaSample * This,
+ AM_MEDIA_TYPE *pMediaType);
+ HRESULT STDCALL ( *IsDiscontinuity )(IMediaSample * This);
+ HRESULT STDCALL ( *SetDiscontinuity )(IMediaSample * This,
+ long bDiscontinuity);
+ HRESULT STDCALL ( *GetMediaTime )(IMediaSample * This,
+ /* [out] */ long long *pTimeStart,
+ /* [out] */ long long *pTimeEnd);
+ HRESULT STDCALL ( *SetMediaTime )(IMediaSample * This,
+ /* [in] */ long long *pTimeStart,
+ /* [in] */ long long *pTimeEnd);
+};
+
+struct _IMediaSample
+{
+ struct _IMediaSample_vt *vt;
+};
+
+struct _IHidden_vt
+{
+ INHERIT_IUNKNOWN();
+
+ HRESULT STDCALL ( *GetSmth )(IHidden * This, int* pv);
+ HRESULT STDCALL ( *SetSmth )(IHidden * This, int v1, int v2);
+ HRESULT STDCALL ( *GetSmth2 )(IHidden * This, int* pv);
+ HRESULT STDCALL ( *SetSmth2 )(IHidden * This, int v1, int v2);
+ HRESULT STDCALL ( *GetSmth3 )(IHidden * This, int* pv);
+ HRESULT STDCALL ( *SetSmth3 )(IHidden * This, int v1, int v2);
+ HRESULT STDCALL ( *GetSmth4 )(IHidden * This, int* pv);
+ HRESULT STDCALL ( *SetSmth4 )(IHidden * This, int v1, int v2);
+ HRESULT STDCALL ( *GetSmth5 )(IHidden * This, int* pv);
+ HRESULT STDCALL ( *SetSmth5 )(IHidden * This, int v1, int v2);
+ HRESULT STDCALL ( *GetSmth6 )(IHidden * This, int* pv);
+};
+
+struct _IHidden
+{
+ struct _IHidden_vt *vt;
+};
+
+struct _IHidden2_vt
+{
+ INHERIT_IUNKNOWN();
+
+ HRESULT STDCALL ( *unk1 )(void);
+ HRESULT STDCALL ( *unk2 )(void);
+ HRESULT STDCALL ( *unk3 )(void);
+ HRESULT STDCALL ( *DecodeGet )(IHidden2* This, int* region);
+ HRESULT STDCALL ( *unk5 )(void);
+ HRESULT STDCALL ( *DecodeSet )(IHidden2* This, int* region);
+ HRESULT STDCALL ( *unk7 )(void);
+ HRESULT STDCALL ( *unk8 )(void);
+};
+
+struct _IHidden2
+{
+ struct _IHidden2_vt *vt;
+};
+
+struct _IDivxFilterInterface
+{
+ struct _IDivxFilterInterface_vt* vt;
+};
+
+struct _IDivxFilterInterface_vt
+{
+ INHERIT_IUNKNOWN();
+
+ HRESULT STDCALL ( *get_PPLevel )(IDivxFilterInterface* This, int* PPLevel); // current postprocessing level
+ HRESULT STDCALL ( *put_PPLevel )(IDivxFilterInterface* This, int PPLevel); // new postprocessing level
+ HRESULT STDCALL ( *put_DefaultPPLevel )(IDivxFilterInterface* This);
+ HRESULT STDCALL ( *put_MaxDelayAllowed )(IDivxFilterInterface* This, int maxdelayallowed);
+ HRESULT STDCALL ( *put_Brightness )(IDivxFilterInterface* This, int brightness);
+ HRESULT STDCALL ( *put_Contrast )(IDivxFilterInterface* This, int contrast);
+ HRESULT STDCALL ( *put_Saturation )(IDivxFilterInterface* This, int saturation);
+ HRESULT STDCALL ( *get_MaxDelayAllowed )(IDivxFilterInterface* This, int* maxdelayallowed);
+ HRESULT STDCALL ( *get_Brightness)(IDivxFilterInterface* This, int* brightness);
+ HRESULT STDCALL ( *get_Contrast)(IDivxFilterInterface* This, int* contrast);
+ HRESULT STDCALL ( *get_Saturation )(IDivxFilterInterface* This, int* saturation);
+ HRESULT STDCALL ( *put_AspectRatio )(IDivxFilterInterface* This, int x, IDivxFilterInterface* This2, int y);
+ HRESULT STDCALL ( *get_AspectRatio )(IDivxFilterInterface* This, int* x, IDivxFilterInterface* This2, int* y);
+};
+#endif /* DS_INTERFACES_H */
diff --git a/src/libw32dll/DirectShow/iunk.h b/src/libw32dll/DirectShow/iunk.h
new file mode 100644
index 000000000..2c672b374
--- /dev/null
+++ b/src/libw32dll/DirectShow/iunk.h
@@ -0,0 +1,59 @@
+#ifndef DS_IUNK_H
+#define DS_IUNK_H
+
+#include "guids.h"
+
+#define DECLARE_IUNKNOWN(CLASSNAME) \
+ long STDCALL (*QueryInterface)(IUnknown * This, GUID* riid, void **ppvObject); \
+ long STDCALL (*AddRef) (IUnknown * This); \
+ long STDCALL (*Release) (IUnknown * This); \
+ int refcount;
+
+#define INHERIT_IUNKNOWN() \
+ long STDCALL (*QueryInterface)(IUnknown * This, GUID* riid, void **ppvObject); \
+ long STDCALL (*AddRef) (IUnknown * This); \
+ long STDCALL (*Release) (IUnknown * This);
+
+#define IMPLEMENT_IUNKNOWN(CLASSNAME) \
+long STDCALL CLASSNAME ## _QueryInterface(IUnknown * This, GUID* riid, void **ppvObject); \
+long STDCALL CLASSNAME ## _AddRef ( \
+ IUnknown * This); \
+long STDCALL CLASSNAME ## _Release ( \
+ IUnknown * This); \
+long STDCALL CLASSNAME ## _QueryInterface(IUnknown * This, GUID* riid, void **ppvObject) \
+{ \
+ CLASSNAME * me = (CLASSNAME *)This; \
+ GUID* r; unsigned int i = 0; \
+ Debug printf(#CLASSNAME "_QueryInterface() called\n");\
+ if (!ppvObject) return 0x80004003; \
+ for(r=me->interfaces; i<sizeof(me->interfaces)/sizeof(me->interfaces[0]); r++, i++) \
+ if(!memcmp(r, riid, 16)) \
+ { \
+ me->vt->AddRef((IUnknown*)This); \
+ *ppvObject=This; \
+ return 0; \
+ } \
+ Debug printf("Failed\n"); \
+ return E_NOINTERFACE; \
+} \
+ \
+long STDCALL CLASSNAME ## _AddRef ( \
+ IUnknown * This) \
+{ \
+ CLASSNAME * me=( CLASSNAME *)This; \
+ Debug printf(#CLASSNAME "_AddRef() called\n"); \
+ return ++(me->refcount); \
+} \
+ \
+long STDCALL CLASSNAME ## _Release ( \
+ IUnknown * This) \
+{ \
+ CLASSNAME* me=( CLASSNAME *)This; \
+ Debug printf(#CLASSNAME "_Release() called\n"); \
+ if(--(me->refcount) ==0) \
+ CLASSNAME ## _Destroy(me); \
+ return 0; \
+}
+
+
+#endif /* DS_IUNK_H */
diff --git a/src/libw32dll/DirectShow/outputpin.c b/src/libw32dll/DirectShow/outputpin.c
new file mode 100644
index 000000000..739ea0a9e
--- /dev/null
+++ b/src/libw32dll/DirectShow/outputpin.c
@@ -0,0 +1,495 @@
+#include "outputpin.h"
+#include "allocator.h"
+#include "iunk.h"
+#include "../wine/winerror.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/*
+ An object beyond interface IEnumMediaTypes.
+ Returned by COutputPin through call IPin::EnumMediaTypes().
+*/
+
+typedef struct _CEnumMediaTypes
+{
+ IEnumMediaTypes_vt *vt;
+ AM_MEDIA_TYPE type;
+ GUID interfaces[2];
+ DECLARE_IUNKNOWN(CEnumMediaTypes)
+}CEnumMediaTypes;
+
+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() called\n");
+ if (!ppMediaTypes)
+ return E_INVALIDARG;
+ if (!pcFetched && (cMediaTypes!=1))
+ return E_INVALIDARG;
+ 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, sizeof(ppMediaTypes[0]->cbFormat));
+ }
+ if (cMediaTypes == 1)
+ return 0;
+ return 1;
+}
+
+/* I expect that these methods are unused. */
+static HRESULT STDCALL CEnumMediaTypes_Skip(IEnumMediaTypes * This,
+ /* [in] */ ULONG cMediaTypes)
+{
+ Debug printf("CEnumMediaTypes::Skip() called\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL CEnumMediaTypes_Reset(IEnumMediaTypes * This)
+{
+ Debug printf("CEnumMediaTypes::Reset() called\n");
+ return 0;
+}
+
+static HRESULT STDCALL CEnumMediaTypes_Clone(IEnumMediaTypes * This,
+ /* [out] */ IEnumMediaTypes **ppEnum)
+{
+ Debug printf("CEnumMediaTypes::Clone() called\n");
+ return E_NOTIMPL;
+}
+
+void CEnumMediaTypes_Destroy(CEnumMediaTypes * this)
+{
+ free(this->vt);
+ free(this);
+}
+
+// IPin->IUnknown methods
+IMPLEMENT_IUNKNOWN(CEnumMediaTypes)
+
+CEnumMediaTypes * CEnumMediaTypes_Create(const AM_MEDIA_TYPE *amtype)
+{
+ CEnumMediaTypes *this;
+ this = malloc(sizeof(CEnumMediaTypes));
+
+ this->refcount = 1;
+ memcpy(&this->type,amtype,sizeof(AM_MEDIA_TYPE));
+
+ this->vt = malloc(sizeof(IEnumMediaTypes_vt));
+ 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;
+}
+
+
+static HRESULT STDCALL COutputPin_AddRef(IUnknown* This)
+{
+ Debug printf("COutputPin_AddRef(%p) called (%d)\n",
+ This, ((COutputPin*)This)->refcount);
+ ((COutputPin*)This)->refcount++;
+ return 0;
+}
+
+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;
+}
+
+static HRESULT STDCALL COutputPin_M_AddRef(IUnknown* This)
+{
+ COutputMemPin* p = (COutputMemPin*) This;
+ Debug printf("COutputPin_MAddRef(%p) called (%p, %d)\n",
+ p, p->parent, p->parent->refcount);
+ p->parent->refcount++;
+ return 0;
+}
+
+static HRESULT STDCALL COutputPin_M_Release(IUnknown* This)
+{
+ COutputMemPin* p = (COutputMemPin*) This;
+ Debug printf("COutputPin_MRelease(%p) called (%p, %d)\n",
+ p, p->parent, p->parent->refcount);
+ if (--p->parent->refcount <= 0)
+ COutputPin_Destroy(p->parent);
+ return 0;
+}
+
+/* Implementation of output pin object. */
+// Constructor
+
+
+static HRESULT STDCALL COutputPin_QueryInterface(IUnknown* This, 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
+static 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;
+ return 0;// XXXXXXXXXXXXX CHECKME XXXXXXXXXXXXXXX
+ // if I put return 0; here, it crashes
+}
+
+static 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;
+}
+
+static HRESULT STDCALL COutputPin_Disconnect(IPin * This)
+{
+ Debug printf("COutputPin_Disconnect() called\n");
+ return 1;
+}
+
+static HRESULT STDCALL COutputPin_ConnectedTo(IPin * This,
+ /* [out] */ IPin **pPin)
+{
+ Debug printf("COutputPin_ConnectedTo() called\n");
+ if (!pPin)
+ return E_INVALIDARG;
+ *pPin = ((COutputPin*)This)->remote;
+ return 0;
+}
+
+static HRESULT STDCALL COutputPin_ConnectionMediaType(IPin * This,
+ /* [out] */ AM_MEDIA_TYPE *pmt)
+{
+ Debug printf("CInputPin::ConnectionMediaType() called\n");
+ if (!pmt)
+ return E_INVALIDARG;
+ *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;
+}
+
+static HRESULT STDCALL COutputPin_QueryPinInfo(IPin * This,
+ /* [out] */ PIN_INFO *pInfo)
+{
+ Debug printf("COutputPin_QueryPinInfo() called\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL COutputPin_QueryDirection(IPin * This,
+ /* [out] */ PIN_DIRECTION *pPinDir)
+{
+ Debug printf("COutputPin_QueryDirection() called\n");
+ if (!pPinDir)
+ return E_INVALIDARG;
+ *pPinDir = PINDIR_INPUT;
+ return 0;
+}
+
+static HRESULT STDCALL COutputPin_QueryId(IPin * This,
+ /* [out] */ LPWSTR *Id)
+{
+ Debug printf("COutputPin_QueryId() called\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL COutputPin_QueryAccept(IPin * This,
+ /* [in] */ const AM_MEDIA_TYPE *pmt)
+{
+ Debug printf("COutputPin_QueryAccept() called\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL COutputPin_EnumMediaTypes(IPin * This,
+ /* [out] */ IEnumMediaTypes **ppEnum)
+{
+ Debug printf("COutputPin_EnumMediaTypes() called\n");
+ if (!ppEnum)
+ return E_INVALIDARG;
+ *ppEnum=(IEnumMediaTypes *)CEnumMediaTypes_Create(&((COutputPin*)This)->type);
+ return 0;
+}
+
+static HRESULT STDCALL COutputPin_QueryInternalConnections(IPin * This,
+ /* [out] */ IPin **apPin,
+ /* [out][in] */ ULONG *nPin)
+{
+ Debug printf("COutputPin_QueryInternalConnections() called\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL COutputPin_EndOfStream(IPin * This)
+{
+ Debug printf("COutputPin_EndOfStream() called\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL COutputPin_BeginFlush(IPin * This)
+{
+ Debug printf("COutputPin_BeginFlush() called\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL COutputPin_EndFlush(IPin * This)
+{
+ Debug printf("COutputPin_EndFlush() called\n");
+ return E_NOTIMPL;
+}
+
+static 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
+
+static HRESULT STDCALL COutputPin_M_QueryInterface(IUnknown* This, GUID* iid, void** ppv)
+{
+ COutputPin* p = (COutputPin*)This;
+ Debug printf("COutputPin_M_QueryInterface() called\n");
+ 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->mempin;
+ p->mempin->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
+
+static HRESULT STDCALL COutputPin_GetAllocator(IMemInputPin * This,
+ /* [out] */ IMemAllocator **ppAllocator)
+{
+ Debug printf("COutputPin_GetAllocator(%p, %p) called\n", This->vt, ppAllocator);
+ *ppAllocator=(IMemAllocator *)MemAllocator_Create();
+ return 0;
+}
+
+static HRESULT STDCALL COutputPin_NotifyAllocator(IMemInputPin * This,
+ /* [in] */ IMemAllocator *pAllocator,
+ /* [in] */ int bReadOnly)
+{
+ Debug printf("COutputPin_NotifyAllocator(%p, %p) called\n", This, pAllocator);
+ ((COutputMemPin*)This)->pAllocator = (MemAllocator*) pAllocator;
+ return 0;
+}
+
+static HRESULT STDCALL COutputPin_GetAllocatorRequirements(IMemInputPin * This,
+ /* [out] */ ALLOCATOR_PROPERTIES *pProps)
+{
+ Debug printf("COutputPin_GetAllocatorRequirements() called\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL COutputPin_Receive(IMemInputPin * This,
+ /* [in] */ IMediaSample *pSample)
+{
+ char* pointer;
+ COutputMemPin* mp= (COutputMemPin*)This;
+ int len = pSample->vt->GetActualDataLength(pSample);
+
+ Debug printf("COutputPin_Receive(%p) called\n", This);
+ if (!pSample)
+ return E_INVALIDARG;
+
+ if (pSample->vt->GetPointer(pSample, (BYTE **)&pointer))
+ return -1;
+
+ if (len == 0)
+ len = pSample->vt->GetSize(pSample);//for iv50
+ //if(me.frame_pointer)memcpy(me.frame_pointer, pointer, len);
+
+ if (mp->frame_pointer)
+ *(mp->frame_pointer) = pointer;
+ if (mp->frame_size_pointer)
+ *(mp->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;
+}
+
+static HRESULT STDCALL COutputPin_ReceiveMultiple(IMemInputPin * This,
+ /* [size_is][in] */ IMediaSample **pSamples,
+ /* [in] */ long nSamples,
+ /* [out] */ long *nSamplesProcessed)
+{
+ Debug printf("COutputPin_ReceiveMultiple() called (UNIMPLEMENTED)\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT STDCALL COutputPin_ReceiveCanBlock(IMemInputPin * This)
+{
+ Debug printf("COutputPin_ReceiveCanBlock() called (UNIMPLEMENTED)\n");
+ return E_NOTIMPL;
+}
+
+COutputPin * COutputPin_Create(const AM_MEDIA_TYPE * vh)
+{
+ COutputPin *this;
+ this = malloc(sizeof(COutputPin));
+ this->refcount = 1;
+ memcpy(&this->type,vh,sizeof(AM_MEDIA_TYPE));
+ this->remote=0;
+ this->vt = malloc(sizeof(IPin_vt));
+ 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 = malloc(sizeof(COutputMemPin));
+ this->mempin->vt = malloc(sizeof(IMemInputPin_vt));
+ this->mempin->vt->QueryInterface = COutputPin_M_QueryInterface;
+ this->mempin->vt->AddRef = COutputPin_M_AddRef;
+ this->mempin->vt->Release = COutputPin_M_Release;
+ this->mempin->vt->GetAllocator = COutputPin_GetAllocator;
+ this->mempin->vt->NotifyAllocator = COutputPin_NotifyAllocator;
+ this->mempin->vt->GetAllocatorRequirements = COutputPin_GetAllocatorRequirements;
+ this->mempin->vt->Receive = COutputPin_Receive;
+ this->mempin->vt->ReceiveMultiple = COutputPin_ReceiveMultiple;
+ this->mempin->vt->ReceiveCanBlock = COutputPin_ReceiveCanBlock;
+
+ this->mempin->frame_size_pointer = 0;
+ this->mempin->frame_pointer = 0;
+ this->mempin->pAllocator = 0;
+ this->mempin->parent = this;
+
+ return this;
+}
+
+void COutputPin_Destroy(COutputPin *this)
+{
+ free(this->vt);
+ free(this->mempin->vt);
+ free(this->mempin);
+ free(this);
+}
+
+void COutputPin_SetFramePointer(COutputPin *this,char** z)
+{ this->mempin->frame_pointer = z; }
+
+void COutputPin_SetPointer2(COutputPin *this,char* p)
+{
+ if (this->mempin->pAllocator)
+ MemAllocator_SetPointer(this->mempin->pAllocator,p);
+}
+
+void COutputPin_SetFrameSizePointer(COutputPin *this,long* z)
+{ this->mempin->frame_size_pointer = z; }
+
+void COutputPin_SetNewFormat(COutputPin *this,const AM_MEDIA_TYPE * a)
+{ memcpy(&this->type,a,sizeof(AM_MEDIA_TYPE)); }
diff --git a/src/libw32dll/DirectShow/outputpin.h b/src/libw32dll/DirectShow/outputpin.h
new file mode 100644
index 000000000..6313f5525
--- /dev/null
+++ b/src/libw32dll/DirectShow/outputpin.h
@@ -0,0 +1,41 @@
+#ifndef DS_OUTPUTPIN_H
+#define DS_OUTPUTPIN_H
+
+/* "output pin" - the one that connects to output of filter. */
+
+#include "allocator.h"
+
+typedef struct _COutputPin COutputPin;
+
+typedef struct _COutputMemPin
+{
+ IMemInputPin_vt *vt;
+ char** frame_pointer;
+ long* frame_size_pointer;
+ MemAllocator* pAllocator;
+ COutputPin* parent;
+}COutputMemPin;
+
+struct _COutputPin
+{
+ IPin_vt *vt;
+ COutputMemPin* mempin;
+ int refcount;
+ AM_MEDIA_TYPE type;
+ IPin* remote;
+};
+
+
+COutputPin * COutputPin_Create(const AM_MEDIA_TYPE * vh);
+
+void COutputPin_Destroy(COutputPin *this);
+
+void COutputPin_SetFramePointer(COutputPin *this,char** z);
+
+void COutputPin_SetPointer2(COutputPin *this,char* p);
+
+void COutputPin_SetFrameSizePointer(COutputPin *this,long* z);
+
+void COutputPin_SetNewFormat(COutputPin *this,const AM_MEDIA_TYPE * a);
+
+#endif /* DS_OUTPUTPIN_H */