summaryrefslogtreecommitdiffstats
path: root/loader/dshow/allocator.c
diff options
context:
space:
mode:
Diffstat (limited to 'loader/dshow/allocator.c')
-rw-r--r--loader/dshow/allocator.c306
1 files changed, 226 insertions, 80 deletions
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;
}