summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--loader/dshow/DS_Filter.c346
-rw-r--r--loader/dshow/DS_Filter.h31
-rw-r--r--loader/dshow/allocator.c306
-rw-r--r--loader/dshow/allocator.h37
-rw-r--r--loader/dshow/cmediasample.c211
-rw-r--r--loader/dshow/cmediasample.h14
-rw-r--r--loader/dshow/guids.c10
-rw-r--r--loader/dshow/guids.h32
-rw-r--r--loader/dshow/inputpin.c772
-rw-r--r--loader/dshow/inputpin.h237
-rw-r--r--loader/dshow/interfaces.h397
-rw-r--r--loader/dshow/iunk.h47
-rw-r--r--loader/dshow/outputpin.c321
-rw-r--r--loader/dshow/outputpin.h26
14 files changed, 1491 insertions, 1296 deletions
diff --git a/loader/dshow/DS_Filter.c b/loader/dshow/DS_Filter.c
index 7cb46c00eb..99124074be 100644
--- a/loader/dshow/DS_Filter.c
+++ b/loader/dshow/DS_Filter.c
@@ -1,223 +1,251 @@
#include "DS_Filter.h"
-//#include "../loader/loader.h"
-#include "libwin32.h"
-//#include <string>
+#include "driver.h"
+#include "com.h"
#include <stdio.h>
#include <string.h>
-#define __MODULE__ "DirectShow generic filter"
-
-using namespace std;
-
-extern "C" int STDCALL expLoadLibraryA(const char*);
-
typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**);
-//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);
-DS_Filter::DS_Filter()
+static void DS_Filter_Start(DS_Filter* This)
{
- m_iHandle = 0;
- m_pFilter = 0;
- m_pInputPin = 0;
- m_pOutputPin = 0;
- m_pSrcFilter = 0;
- m_pParentFilter = 0;
- m_pOurInput = 0;
- m_pOurOutput = 0;
- m_pAll = 0;
- m_pImp = 0;
- m_iState = 0;
+ HRESULT hr;
+
+ if (This->m_iState != 1)
+ return;
+
+ //Debug printf("DS_Filter_Start(%p)\n", This);
+ 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 || !This->m_pAll)
+ {
+ 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;
}
-DS_Filter::~DS_Filter()
+static void DS_Filter_Stop(DS_Filter* This)
{
- //cout << "Destruction of DS_FILTER" << endl;
- Stop();
- destroy();
- //cout << "Destruction of DS_FILTER done" << endl;
+ if (This->m_iState == 2)
+ {
+ This->m_iState = 1;
+ //Debug printf("DS_Filter_Stop(%p)\n", This);
+ if (This->m_pFilter)
+ {
+ //printf("vt: %p\n", m_pFilter->vt);
+ //printf("vtstop %p\n", 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;
+ }
}
-void DS_Filter::destroy()
+void DS_Filter_Destroy(DS_Filter* This)
{
- if (m_iState == 0)
- return;
- m_iState = 0;
-
- if (m_pOurInput)
- m_pOurInput->vt->Release((IUnknown*)m_pOurInput);
- if (m_pInputPin)
- m_pInputPin->vt->Disconnect(m_pInputPin);
- if (m_pOutputPin)
- m_pOutputPin->vt->Disconnect(m_pOutputPin);
- if (m_pFilter)
- m_pFilter->vt->Release((IUnknown*)m_pFilter);
- if (m_pOutputPin)
- m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin);
- if (m_pInputPin)
- m_pInputPin->vt->Release((IUnknown*)m_pInputPin);
- if (m_pImp)
- m_pImp->vt->Release((IUnknown*)m_pImp);
-
- delete m_pOurOutput;
- delete m_pParentFilter;
- delete m_pSrcFilter;
+ This->Stop(This);
+
+ 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);
+
+ if (This->m_pOurOutput)
+ This->m_pOurOutput->vt->Release((IUnknown*)This->m_pOurOutput);
+ if (This->m_pParentFilter)
+ This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pParentFilter);
+ if (This->m_pSrcFilter)
+ This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pSrcFilter);
// FIXME - we are still leaving few things allocated!
- if (m_iHandle)
- FreeLibrary(m_iHandle);
+ if (This->m_iHandle)
+ FreeLibrary(This->m_iHandle);
+
+ free(This);
+
+ CodecRelease();
}
-void DS_Filter::Create(const char* dllname, const GUID* id,
- AM_MEDIA_TYPE* in_fmt,
- AM_MEDIA_TYPE* out_fmt)
+DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
+ AM_MEDIA_TYPE* in_fmt,
+ AM_MEDIA_TYPE* out_fmt)
{
- try
+ DS_Filter* This = (DS_Filter*) malloc(sizeof(DS_Filter));
+ if (!This)
+ return NULL;
+
+ CodecAlloc();
+
+ This->m_pFilter = NULL;
+ This->m_pInputPin = NULL;
+ This->m_pOutputPin = NULL;
+ This->m_pSrcFilter = NULL;
+ This->m_pParentFilter = NULL;
+ This->m_pOurInput = NULL;
+ This->m_pOurOutput = NULL;
+ This->m_pAll = NULL;
+ This->m_pImp = NULL;
+ This->m_iState = 0;
+
+ This->Start = DS_Filter_Start;
+ This->Stop = DS_Filter_Stop;
+
+ for (;;)
{
- m_iHandle = expLoadLibraryA(dllname);
- if (!m_iHandle)
+ HRESULT result;
+ GETCLASS func;
+ struct IClassFactory* factory = NULL;
+ struct IUnknown* object = NULL;
+ IEnumPins* enum_pins = 0;
+ IPin* array[256];
+ ULONG fetched;
+ unsigned int i;
+
+ This->m_iHandle = LoadLibraryA(dllname);
+ if (!This->m_iHandle)
{
- char e[256];
- snprintf((char *)&e[0], 256, "Could not open DirectShow DLL: %.200s", dllname);
- throw FATAL(e);
+ printf("Could not open DirectShow DLL: %.200s\n", dllname);
+ break;
}
- GETCLASS func = (GETCLASS)GetProcAddress(m_iHandle, "DllGetClassObject");
+ func = (GETCLASS)GetProcAddress(This->m_iHandle, "DllGetClassObject");
if (!func)
{
- char e[256];
- snprintf((char *)&e[0], 256, "Illegal or corrupt DirectShow DLL: %.200s", dllname);
- throw FATAL(e);
+ printf("Illegal or corrupt DirectShow DLL: %.200s\n", dllname);
+ break;
}
-
- HRESULT result;
- IClassFactory* factory = 0;
result = func(id, &IID_IClassFactory, (void**)&factory);
if (result || !factory)
- throw FATAL("No such class object");;
-
- IUnknown* object = 0;
+ {
+ printf("No such class object\n");
+ break;
+ }
result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object);
factory->vt->Release((IUnknown*)factory);
if (result || !object)
- throw FATAL("Class factory failure");
-
- result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&m_pFilter);
+ {
+ printf("Class factory failure\n");
+ break;
+ }
+ result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&This->m_pFilter);
object->vt->Release((IUnknown*)object);
- if (result || !m_pFilter)
- throw FATAL("Object does not have IBaseFilter interface");
-
- IEnumPins* enum_pins = 0;
+ if (result || !This->m_pFilter)
+ {
+ printf("Object does not have IBaseFilter interface\n");
+ break;
+ }
// enumerate pins
- result = m_pFilter->vt->EnumPins(m_pFilter, &enum_pins);
+ result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins);
if (result || !enum_pins)
- throw FATAL("Could not enumerate pins");
+ {
+ printf("Could not enumerate pins\n");
+ break;
+ }
- IPin* array[256];
- ULONG fetched;
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 (unsigned i = 0; i < fetched; i++)
+ for (i = 0; i < fetched; i++)
{
int direction = -1;
array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction);
- if (!m_pInputPin && direction == 0)
+ if (!This->m_pInputPin && direction == 0)
{
- m_pInputPin = array[i];
- m_pInputPin->vt->AddRef((IUnknown*)m_pInputPin);
+ This->m_pInputPin = array[i];
+ This->m_pInputPin->vt->AddRef((IUnknown*)This->m_pInputPin);
}
- if (!m_pOutputPin && direction == 1)
+ if (!This->m_pOutputPin && direction == 1)
{
- m_pOutputPin = array[i];
- m_pOutputPin->vt->AddRef((IUnknown*)m_pOutputPin);
+ This->m_pOutputPin = array[i];
+ This->m_pOutputPin->vt->AddRef((IUnknown*)This->m_pOutputPin);
}
array[i]->vt->Release((IUnknown*)(array[i]));
}
- if (!m_pInputPin)
- throw FATAL("Input pin not found");
- if (!m_pOutputPin)
- throw FATAL("Output pin not found");
-
- result = m_pInputPin->vt->QueryInterface((IUnknown*)m_pInputPin,
- &IID_IMemInputPin,
- (void**)&m_pImp);
- if (result)
- throw FATAL("Error getting IMemInputPin interface");
- m_pOurType = in_fmt;
- m_pDestType = out_fmt;
- result = m_pInputPin->vt->QueryAccept(m_pInputPin, m_pOurType);
+ if (!This->m_pInputPin)
+ {
+ printf("Input pin not found\n");
+ break;
+ }
+ if (!This->m_pOutputPin)
+ {
+ printf("Output pin not found\n");
+ break;
+ }
+ result = This->m_pInputPin->vt->QueryInterface((IUnknown*)This->m_pInputPin,
+ &IID_IMemInputPin,
+ (void**)&This->m_pImp);
if (result)
- throw FATAL("Source format is not accepted");
-
- m_pParentFilter = new CBaseFilter2;
- m_pSrcFilter = new CBaseFilter(*m_pOurType, m_pParentFilter);
- m_pOurInput = m_pSrcFilter->GetPin();
- m_pOurInput->vt->AddRef((IUnknown*)m_pOurInput);
+ {
+ printf("Error getting IMemInputPin interface\n");
+ break;
+ }
- result = m_pInputPin->vt->ReceiveConnection(m_pInputPin,
- m_pOurInput,
- m_pOurType);
+ This->m_pOurType = in_fmt;
+ This->m_pDestType = out_fmt;
+ result = This->m_pInputPin->vt->QueryAccept(This->m_pInputPin, This->m_pOurType);
if (result)
- throw FATAL("Error connecting to input pin");
+ {
+ printf("Source format is not accepted\n");
+ break;
+ }
+ This->m_pParentFilter = CBaseFilter2Create();
+ This->m_pSrcFilter = CBaseFilterCreate(This->m_pOurType, This->m_pParentFilter);
+ This->m_pOurInput = This->m_pSrcFilter->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)
+ {
+ printf("Error connecting to input pin\n");
+ break;
+ }
- m_pOurOutput = new COutputPin(*m_pDestType);
+ This->m_pOurOutput = COutputPinCreate(This->m_pDestType);
- //extern void trapbug();
- //trapbug();
- result = m_pOutputPin->vt->ReceiveConnection(m_pOutputPin,
- m_pOurOutput,
- m_pDestType);
+ 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);
- throw FATAL("Error connecting to output pin");
+ printf("Error connecting to output pin\n");
+ break;
}
printf("Using DirectShow codec: %s\n", dllname);
- m_iState = 1;
- }
- catch (FatalError e)
- {
- //e.PrintAll();
- destroy();
- throw;
- }
-}
-
-void DS_Filter::Start()
-{
- if (m_iState != 1)
- return;
-
- HRESULT hr=m_pFilter->vt->Run(m_pFilter, 0);
- if (hr != 0)
- {
- Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr);
+ This->m_iState = 1;
+ break;
}
- hr = m_pImp->vt->GetAllocator(m_pImp, &m_pAll);
- if (hr)
- {
- Debug printf("Error getting IMemAllocator interface %x\n", (int)hr);
- m_pImp->vt->Release((IUnknown*)m_pImp);
- return;
- }
- m_pImp->vt->NotifyAllocator(m_pImp, m_pAll, 0);
- m_iState = 2;
-}
-void DS_Filter::Stop()
-{
- if (m_iState == 2)
+ if (This->m_iState != 1)
{
- m_pAll->vt->Release((IUnknown*)m_pAll);
- if (m_pFilter)
- m_pFilter->vt->Stop(m_pFilter); // causes weird crash ??? FIXME
- else
- printf("m_pFilter is NULL!\n");
- m_pAll = 0;
- m_iState = 1;
+ DS_Filter_Destroy(This);
+ This = 0;
}
+ return This;
}
diff --git a/loader/dshow/DS_Filter.h b/loader/dshow/DS_Filter.h
index 2f10849e2b..fd8166b11c 100644
--- a/loader/dshow/DS_Filter.h
+++ b/loader/dshow/DS_Filter.h
@@ -1,41 +1,46 @@
#ifndef DS_FILTER_H
#define DS_FILTER_H
-#include "interfaces.h"
#include "inputpin.h"
#include "outputpin.h"
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
/**
User will allocate and fill format structures, call Create(),
and then set up m_pAll.
**/
-struct DS_Filter
+typedef struct _DS_Filter DS_Filter;
+struct _DS_Filter
{
- DS_Filter();
- virtual ~DS_Filter();
- void Start();
- void Stop();
-
int m_iHandle;
IBaseFilter* m_pFilter;
IPin* m_pInputPin;
IPin* m_pOutputPin;
-
+
CBaseFilter* m_pSrcFilter;
CBaseFilter2* m_pParentFilter;
IPin* m_pOurInput;
COutputPin* m_pOurOutput;
-
+
AM_MEDIA_TYPE *m_pOurType, *m_pDestType;
IMemAllocator* m_pAll;
IMemInputPin* m_pImp;
int m_iState;
- void Create(const char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt);
- void SetPointer(char* pointer);
-
- void destroy();
+ void ( *Start )(DS_Filter*);
+ void ( *Stop )(DS_Filter*);
};
+DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
+ AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt);
+void DS_Filter_Destroy(DS_Filter* This);
+
+#if defined(__cplusplus)
+}
+#endif
+
#endif /* DS_FILTER_H */
diff --git a/loader/dshow/allocator.c b/loader/dshow/allocator.c
index ce30e615d2..6b960c570e 100644
--- a/loader/dshow/allocator.c
+++ b/loader/dshow/allocator.c
@@ -3,62 +3,136 @@
#include "wine/winerror.h"
#include <stdio.h>
-//#undef Debug
-//#define Debug
+static int AllocatorKeeper = 0;
-using namespace std;
+static inline int avm_list_size(avm_list_t* head)
+{
+ avm_list_t* it = head;
+ int i = 0;
+ if (it)
+ {
+ for (;;)
+ {
+ i++;
+ it = it->next;
+ if (it == head)
+ break;
+ }
+ }
+ return i;
+}
-class AllocatorKeeper
+static inline int avm_list_print(avm_list_t* head)
{
-public:
- AllocatorKeeper()
+ avm_list_t* it = head;
+ int i = 0;
+ printf("Head: %p\n", head);
+ if (it)
{
- RegisterComClass(&CLSID_MemoryAllocator, MemAllocator::CreateAllocator);
+ for (;;)
+ {
+ i++;
+ printf("%d: member: %p next: %p prev: %p\n",
+ i, it->member, it->next, it->prev);
+ it = it->next;
+ if (it == head)
+ break;
+ }
}
- ~AllocatorKeeper()
+ return i;
+}
+
+static inline avm_list_t* avm_list_add_head(avm_list_t* head, void* member)
+{
+ avm_list_t* n = (avm_list_t*) malloc(sizeof(avm_list_t));
+ n->member = member;
+
+ if (!head)
{
- UnregisterComClass(&CLSID_MemoryAllocator, MemAllocator::CreateAllocator);
+ head = n;
+ head->prev = head;
}
-};
-static AllocatorKeeper keeper;
+ n->prev = head->prev;
+ head->prev = n;
+ n->next = head;
-GUID MemAllocator::interfaces[]=
+ return n;
+}
+
+static inline avm_list_t* avm_list_add_tail(avm_list_t* head, void* member)
{
- IID_IUnknown,
- IID_IMemAllocator,
-};
+ avm_list_t* n = avm_list_add_head(head, member);
+ return (!head) ? n : head;
+}
-IMPLEMENT_IUNKNOWN(MemAllocator)
+static inline avm_list_t* avm_list_del_head(avm_list_t* head)
+{
+ avm_list_t* n = 0;
+ if (head)
+ {
+ if (head->next != head)
+ {
+ n = head->next;
+ head->prev->next = head->next;
+ head->next->prev = head->prev;
+ }
+
+ free(head);
+ }
+
+ return n;
+}
+
+static inline avm_list_t* avm_list_find(avm_list_t* head, void* member)
+{
+ avm_list_t* it = head;
+ if (it)
+ {
+ for (;;)
+ {
+ if (it->member == member)
+ return it;
+ it = it->next;
+ if (it == head)
+ break;
+ }
+ }
+ return NULL;
+}
-long MemAllocator::CreateAllocator(GUID* clsid, GUID* iid, void** ppv)
+static long MemAllocator_CreateAllocator(GUID* clsid, GUID* iid, void** ppv)
{
- if(!ppv)return -1;
- *ppv=0;
- if(memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID)))
+ IMemAllocator* p;
+ int result;
+ if (!ppv)
+ return -1;
+ *ppv = 0;
+ if (memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID)))
return -1;
- IMemAllocator* p=new MemAllocator;
- int result=p->vt->QueryInterface((IUnknown*)p, iid, ppv);
+ p = (IMemAllocator*) MemAllocatorCreate();
+ result = p->vt->QueryInterface((IUnknown*)p, iid, ppv);
p->vt->Release((IUnknown*)p);
+
return result;
}
-
static HRESULT STDCALL MemAllocator_SetProperties(IMemAllocator * This,
/* [in] */ ALLOCATOR_PROPERTIES *pRequest,
/* [out] */ ALLOCATOR_PROPERTIES *pActual)
{
- Debug printf("MemAllocator_SetProperties() called\n");
+ MemAllocator* me = (MemAllocator*)This;
+ Debug printf("MemAllocator_SetProperties(%p) called\n", This);
if (!pRequest || !pActual)
return E_INVALIDARG;
if (pRequest->cBuffers<=0 || pRequest->cbBuffer<=0)
return E_FAIL;
- MemAllocator* me = (MemAllocator*)This;
- if (me->used_list.size() || me->free_list.size())
+ if (me->used_list != 0 || me->free_list != 0)
return E_FAIL;
me->props = *pRequest;
*pActual = *pRequest;
+
return 0;
}
@@ -71,34 +145,56 @@ static HRESULT STDCALL MemAllocator_GetProperties(IMemAllocator * This,
if (((MemAllocator*)This)->props.cbBuffer<0)
return E_FAIL;
*pProps=((MemAllocator*)This)->props;
+
return 0;
}
static HRESULT STDCALL MemAllocator_Commit(IMemAllocator * This)
{
+ MemAllocator* me = (MemAllocator*)This;
+ int i;
Debug printf("MemAllocator_Commit(%p) called\n", This);
- MemAllocator* me=(MemAllocator*)This;
if (((MemAllocator*)This)->props.cbBuffer < 0)
return E_FAIL;
- if (me->used_list.size() || me->free_list.size())
+ if (me->used_list || me->free_list)
return E_INVALIDARG;
- for(int i = 0; i<me->props.cBuffers; i++)
- me->free_list.push_back(new CMediaSample(me, me->props.cbBuffer));
+ for (i = 0; i < me->props.cBuffers; i++)
+ {
+ CMediaSample* sample = CMediaSampleCreate((IMemAllocator*)me,
+ me->props.cbBuffer);
+ //printf("FREEEEEEEEEEEE ADDED %p\n", sample);
+
+ me->free_list = avm_list_add_tail(me->free_list, sample);
+ //avm_list_print(me->free_list);
+ }
+ //printf("Added mem %p: lsz: %d %d size: %d\n", me, avm_list_size(me->free_list), me->props.cBuffers, me->props.cbBuffer);
return 0;
}
static HRESULT STDCALL MemAllocator_Decommit(IMemAllocator * This)
{
- Debug printf("MemAllocator_Decommit(%p) called\n", This);
MemAllocator* me=(MemAllocator*)This;
- list<CMediaSample*>::iterator it;
- for(it=me->free_list.begin(); it!=me->free_list.end(); it++)
- delete *it;
- for(it=me->used_list.begin(); it!=me->used_list.end(); it++)
- delete *it;
- me->free_list.clear();
- me->used_list.clear();
+ Debug printf("MemAllocator_Decommit(%p) called\n", This);
+ //printf("Deleted mem %p: %d %d\n", me, me->free_list.size(), me->used_list.size());
+ while (me->used_list)
+ {
+ CMediaSample* sample = (CMediaSample*) me->used_list->member;
+ //printf("****************** Decommiting USED %p\n", sample);
+ //sample->vt->Release((IUnknown*)sample);
+ CMediaSample_Destroy((CMediaSample*)sample);
+ me->used_list = avm_list_del_head(me->used_list);
+ }
+
+ while (me->free_list)
+ {
+ CMediaSample* sample = (CMediaSample*) me->free_list->member;
+ //printf("****************** Decommiting FREE %p\n", sample);
+ //sample->vt->Release((IUnknown*)sample);
+ CMediaSample_Destroy((CMediaSample*)sample);
+ me->free_list = avm_list_del_head(me->free_list);
+ }
+
return 0;
}
@@ -108,71 +204,121 @@ static HRESULT STDCALL MemAllocator_GetBuffer(IMemAllocator * This,
/* [in] */ REFERENCE_TIME *pEndTime,
/* [in] */ DWORD dwFlags)
{
- Debug printf("MemAllocator_GetBuffer(%p) called\n", This);
MemAllocator* me = (MemAllocator*)This;
- if (me->free_list.size() == 0)
+ CMediaSample* sample;
+ Debug printf("MemAllocator_GetBuffer(%p) called %d %d\n", This,
+ avm_list_size(me->used_list), avm_list_size(me->free_list));
+ if (!me->free_list)
{
Debug printf("No samples available\n");
return E_FAIL;//should block here if no samples are available
}
- list<CMediaSample*>::iterator it = me->free_list.begin();
- me->used_list.push_back(*it);
- *ppBuffer = *it;
- (*ppBuffer)->vt->AddRef((IUnknown*)*ppBuffer);
+
+ sample = (CMediaSample*) me->free_list->member;
+ me->free_list = avm_list_del_head(me->free_list);
+ me->used_list = avm_list_add_tail(me->used_list, sample);
+
+ //printf("MemAllocator getbuffer: %p %d %d\n", sample, avm_list_size(me->used_list), avm_list_size(me->free_list));
+
+ *ppBuffer = (IMediaSample*) sample;
+ sample->vt->AddRef((IUnknown*) sample);
if (me->new_pointer)
{
- if(me->modified_sample)
- me->modified_sample->ResetPointer();
- (*it)->SetPointer(me->new_pointer);
- me->modified_sample=*it;
+ if (me->modified_sample)
+ me->modified_sample->ResetPointer(me->modified_sample);
+ sample->SetPointer(sample, me->new_pointer);
+ me->modified_sample = sample;
me->new_pointer = 0;
}
- me->free_list.remove(*it);
return 0;
}
-static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator * This,
- /* [in] */ IMediaSample *pBuffer)
+static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator* This,
+ /* [in] */ IMediaSample* pBuffer)
{
- Debug printf("MemAllocator_ReleaseBuffer(%p) called\n", This);
MemAllocator* me = (MemAllocator*)This;
- list<CMediaSample*>::iterator it;
- for (it = me->used_list.begin(); it != me->used_list.end(); it++)
- if (*it == pBuffer)
+ Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This,
+ avm_list_size(me->used_list), avm_list_size(me->free_list));
+
+ for (;;)
+ {
+ avm_list_t* l = avm_list_find(me->used_list, pBuffer);
+ if (l)
{
- me->used_list.erase(it);
- me->free_list.push_back((CMediaSample*)pBuffer);
- return 0;
+ CMediaSample* sample = (CMediaSample*) l->member;
+ me->used_list = avm_list_del_head(me->used_list);
+ me->free_list = avm_list_add_head(me->free_list, sample);
+ //printf("****************** RELEASED OK %p %p\n", me->used_list, me->free_list);
+
+ return 0;
}
- Debug printf("Releasing unknown buffer\n");
+ else
+ break;
+ }
+ Debug printf("MemAllocator_ReleaseBuffer(%p) releasing unknown buffer!!!! %p\n", This, pBuffer);
return E_FAIL;
}
-MemAllocator::MemAllocator()
+
+static void MemAllocator_SetPointer(MemAllocator* This, char* pointer)
{
- Debug printf("MemAllocator::MemAllocator() called\n");
- vt = new IMemAllocator_vt;
- vt->QueryInterface = QueryInterface;
- vt->AddRef = AddRef;
- vt->Release = Release;
- vt->SetProperties = MemAllocator_SetProperties;
- vt->GetProperties = MemAllocator_GetProperties;
- vt->Commit = MemAllocator_Commit;
- vt->Decommit = MemAllocator_Decommit;
- vt->GetBuffer = MemAllocator_GetBuffer;
- vt->ReleaseBuffer = MemAllocator_ReleaseBuffer;
+ This->new_pointer = pointer;
+}
- refcount = 1;
- props.cBuffers = 1;
- props.cbBuffer = 65536; /* :/ */
- props.cbAlign = props.cbPrefix = 0;
+static void MemAllocator_ResetPointer(MemAllocator* This)
+{
+ if (This->modified_sample)
+ {
+ This->modified_sample->ResetPointer(This->modified_sample);
+ This->modified_sample = 0;
+ }
+}
- new_pointer=0;
- modified_sample=0;
+void MemAllocator_Destroy(MemAllocator* This)
+{
+ Debug printf("MemAllocator_Destroy(%p) called (%d, %d)\n", This, This->refcount, AllocatorKeeper);
+ if (--AllocatorKeeper == 0)
+ UnregisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator);
+ free(This->vt);
+ free(This);
}
-MemAllocator::~MemAllocator()
+IMPLEMENT_IUNKNOWN(MemAllocator)
+
+MemAllocator* MemAllocatorCreate()
{
- Debug printf("MemAllocator::~MemAllocator() called\n");
- delete vt;
+ MemAllocator* This = (MemAllocator*) malloc(sizeof(MemAllocator));
+ Debug printf("MemAllocatorCreate() called -> %p\n", This);
+
+ This->refcount = 1;
+ This->props.cBuffers = 1;
+ This->props.cbBuffer = 65536; /* :/ */
+ This->props.cbAlign = This->props.cbPrefix = 0;
+
+ This->vt = (IMemAllocator_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->SetPointer = MemAllocator_SetPointer;
+ This->ResetPointer = MemAllocator_ResetPointer;
+
+ This->new_pointer = 0;
+ This->modified_sample = 0;
+ This->used_list = 0;
+ This->free_list = 0;
+
+ This->interfaces[0]=IID_IUnknown;
+ This->interfaces[1]=IID_IMemAllocator;
+
+ if (AllocatorKeeper++ == 0)
+ RegisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator);
+
+ return This;
}
diff --git a/loader/dshow/allocator.h b/loader/dshow/allocator.h
index 1e9d7d5556..f853001d37 100644
--- a/loader/dshow/allocator.h
+++ b/loader/dshow/allocator.h
@@ -3,33 +3,30 @@
#include "interfaces.h"
#include "cmediasample.h"
-#include "iunk.h"
-#include <list>
+typedef struct avm_list_t
+{
+ struct avm_list_t* next;
+ struct avm_list_t* prev;
+ void* member;
+} avm_list_t;
-struct MemAllocator: public IMemAllocator
+typedef struct _MemAllocator MemAllocator;
+struct _MemAllocator
{
+ IMemAllocator_vt* vt;
ALLOCATOR_PROPERTIES props;
- std::list<CMediaSample*> used_list;
- std::list<CMediaSample*> free_list;
+ avm_list_t* used_list;
+ avm_list_t* free_list;
char* new_pointer;
CMediaSample* modified_sample;
- static GUID interfaces[];
- DECLARE_IUNKNOWN(MemAllocator)
-
- MemAllocator();
- ~MemAllocator();
- void SetPointer(char* pointer) { new_pointer=pointer; }
- void ResetPointer()
- {
- if (modified_sample)
- {
- modified_sample->ResetPointer();
- modified_sample=0;
- }
- }
+ GUID interfaces[2];
+ DECLARE_IUNKNOWN();
- static long CreateAllocator(GUID* clsid, GUID* iid, void** ppv);
+ void ( *SetPointer )(MemAllocator* This, char* pointer);
+ void ( *ResetPointer )(MemAllocator* This);
};
+MemAllocator* MemAllocatorCreate();
+
#endif /* DS_ALLOCATOR_H */
diff --git a/loader/dshow/cmediasample.c b/loader/dshow/cmediasample.c
index 983ddbaeea..d927bb2264 100644
--- a/loader/dshow/cmediasample.c
+++ b/loader/dshow/cmediasample.c
@@ -3,23 +3,23 @@
#include <stdio.h>
#include <string.h>
-static long STDCALL CMediaSample_QueryInterface(IUnknown * This,
+static long STDCALL CMediaSample_QueryInterface(IUnknown* This,
/* [in] */ IID* iid,
/* [iid_is][out] */ void **ppv)
{
- Debug printf("CMediaSample_QueryInterface() called\n");
+ Debug printf("CMediaSample_QueryInterface(%p) called\n", This);
if (!ppv)
return E_INVALIDARG;
- if (!memcmp(iid, &IID_IUnknown, 16))
+ if (memcmp(iid, &IID_IUnknown, sizeof(*iid)) == 0)
{
- *ppv=(void*)This;
- This->vt->AddRef(This);
+ *ppv = (void*)This;
+ ((IMediaSample*) This)->vt->AddRef(This);
return 0;
}
- if (!memcmp(iid, &IID_IMediaSample, 16))
+ if (memcmp(iid, &IID_IMediaSample, sizeof(*iid)) == 0)
{
- *ppv=(void*)This;
- This->vt->AddRef(This);
+ *ppv = (void*)This;
+ ((IMediaSample*) This)->vt->AddRef(This);
return 0;
}
return E_NOINTERFACE;
@@ -27,26 +27,39 @@ static long STDCALL CMediaSample_QueryInterface(IUnknown * This,
static long STDCALL CMediaSample_AddRef(IUnknown* This)
{
- Debug printf("CMediaSample_AddRef() called\n");
+ Debug printf("CMediaSample_AddRef(%p) called\n", This);
((CMediaSample*)This)->refcount++;
return 0;
}
+void CMediaSample_Destroy(CMediaSample* This)
+{
+
+ Debug printf("CMediaSample_Destroy(%p) called (ref:%d)\n", This, This->refcount);
+ free(This->vt);
+ free(This->own_block);
+ if (This->media_type.pbFormat)
+ CoTaskMemFree(This->media_type.pbFormat);
+ free(This);
+}
+
static long STDCALL CMediaSample_Release(IUnknown* This)
{
- Debug printf("%p: CMediaSample_Release() called, new refcount %d\n",
- This, ((CMediaSample*)This)->refcount-1);
CMediaSample* parent=(CMediaSample*)This;
- if (--((CMediaSample*)This)->refcount==0)
+ Debug printf("CMediaSample_Release(%p) called (new ref:%d)\n",
+ This, ((CMediaSample*)This)->refcount-1);
+ if (--((CMediaSample*)This)->refcount == 0)
+ {
<