summaryrefslogtreecommitdiff
path: root/src/libw32dll/DirectShow/allocator.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libw32dll/DirectShow/allocator.c')
-rw-r--r--src/libw32dll/DirectShow/allocator.c419
1 files changed, 224 insertions, 195 deletions
diff --git a/src/libw32dll/DirectShow/allocator.c b/src/libw32dll/DirectShow/allocator.c
index f9f6826ea..bc129dc42 100644
--- a/src/libw32dll/DirectShow/allocator.c
+++ b/src/libw32dll/DirectShow/allocator.c
@@ -1,163 +1,141 @@
#include "allocator.h"
-#include "cmediasample.h"
-#include "../wine/com.h"
-#include "../wine/winerror.h"
+#include "com.h"
+#include "wine/winerror.h"
#include <stdio.h>
-#include <stdlib.h>
-//#undef Debug
-//#define Debug
+static int AllocatorKeeper = 0;
-/*
-class AllocatorKeeper
+static inline int avm_list_size(avm_list_t* head)
{
-public:
- AllocatorKeeper()
+ avm_list_t* it = head;
+ int i = 0;
+ if (it)
{
- 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))
+ for (;;)
{
- CMediaSample** t = this->m_Type;
- CMediaSample_vector_copy(this, this->m_Type, this->m_uiSize, this->m_uiAlloc / 2);
- free(t);
+ i++;
+ it = it->next;
+ if (it == head)
+ break;
}
+ }
+ return i;
}
-void CMediaSample_vector_erase(CMediaSample_vector *this, CMediaSample** pos)
+static inline int avm_list_print(avm_list_t* head)
{
- if (this->m_uiSize > 0)
+ avm_list_t* it = head;
+ int i = 0;
+ printf("Head: %p\n", head);
+ if (it)
+ {
+ for (;;)
{
- while (pos < CMediaSample_vector_end(this) - 1)
- {
- pos[0] = pos[1];
- pos++;
- }
- CMediaSample_vector_pop_back(this);
+ i++;
+ printf("%d: member: %p next: %p prev: %p\n",
+ i, it->member, it->next, it->prev);
+ it = it->next;
+ if (it == head)
+ break;
}
+ }
+ return i;
}
-
-void CMediaSample_vector_push_back(CMediaSample_vector *this, CMediaSample *m)
+
+static inline avm_list_t* avm_list_add_head(avm_list_t* head, void* member)
{
- 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;
-}
+ avm_list_t* n = (avm_list_t*) malloc(sizeof(avm_list_t));
+ n->member = member;
+
+ if (!head)
+ {
+ head = n;
+ head->prev = head;
+ }
+ n->prev = head->prev;
+ head->prev = n;
+ n->next = head;
-int CMediaSample_vector_size(CMediaSample_vector *this)
-{ return this->m_uiSize; }
+ return n;
+}
-void CMediaSample_vector_clear(CMediaSample_vector *this)
+static inline avm_list_t* avm_list_add_tail(avm_list_t* head, void* member)
{
- if (this->m_uiAlloc > 4)
+ avm_list_t* n = avm_list_add_head(head, member);
+ return (!head) ? n : head;
+}
+
+static inline avm_list_t* avm_list_del_head(avm_list_t* head)
+{
+ avm_list_t* n = 0;
+
+ if (head)
+ {
+ if (head->next != head)
{
- free( this->m_Type );
- this->m_uiAlloc = 4;
- this->m_Type = malloc(this->m_uiAlloc*sizeof(CMediaSample *));
+ n = head->next;
+ head->prev->next = head->next;
+ head->next->prev = head->prev;
}
- this->m_uiSize = 0;
+ free(head);
+ }
+ return n;
}
-CMediaSample_vector * CMediaSample_vector_create()
+static inline avm_list_t* avm_list_find(avm_list_t* head, void* member)
{
- 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;
+ avm_list_t* it = head;
+ if (it)
+ {
+ for (;;)
+ {
+ if (it->member == member)
+ return it;
+ it = it->next;
+ if (it == head)
+ break;
+ }
+ }
+ return NULL;
}
-
-IMPLEMENT_IUNKNOWN(MemAllocator)
-
-long MemAllocator_CreateAllocator(GUID* clsid, GUID* iid, void** ppv)
+static long MemAllocator_CreateAllocator(GUID* clsid, GUID* iid, void** ppv)
{
- MemAllocator* p;
+ IMemAllocator* p;
int result;
-
- if (!ppv) return -1;
+ 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 = (IMemAllocator*) MemAllocatorCreate();
+ 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);
+ return result;
}
-
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");
+ Debug printf("MemAllocator_SetProperties(%p) called\n", This);
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))
+ if (me->used_list != 0 || me->free_list != 0)
return E_FAIL;
- me->props = *pRequest;
+
*pActual = *pRequest;
+ //if (pActual->cbBuffer == 2)
+ // pActual->cbBuffer = 576;
+
+ me->props = *pActual;
+
return 0;
}
@@ -170,40 +148,55 @@ 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)
{
- int i;
MemAllocator* me = (MemAllocator*)This;
-
+ int i;
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))
+ if (me->used_list || 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));
+ for (i = 0; i < me->props.cBuffers; i++)
+ {
+ CMediaSample* sample = CMediaSampleCreate((IMemAllocator*)me,
+ me->props.cbBuffer);
+ if (!sample)
+ return E_OUTOFMEMORY;
+ //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: %d %d size: %d\n", me, me->free_list.size(), me->props.cBuffers, me->props.cbBuffer);
+ //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)
{
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);
+ while (me->used_list)
+ {
+ me->free_list = avm_list_add_tail(me->free_list,
+ (CMediaSample*) me->used_list->member);
+ 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;
}
@@ -214,94 +207,130 @@ static HRESULT STDCALL MemAllocator_GetBuffer(IMemAllocator * This,
/* [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)
+ CMediaSample* sample;
+ Debug printf("MemAllocator_ReleaseBuffer(%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
}
- CMediaSample_vector_push_back(me->used_list,*it);
- *ppBuffer = (IMediaSample *)*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);
+
+ *ppBuffer = (IMediaSample*) sample;
+ sample->vt->AddRef((IUnknown*) sample);
if (me->new_pointer)
{
- if(me->modified_sample)
+ if (me->modified_sample)
me->modified_sample->ResetPointer(me->modified_sample);
- (*it)->SetPointer(*it,me->new_pointer);
- me->modified_sample = *it;
+ sample->SetPointer(sample, me->new_pointer);
+ me->modified_sample = sample;
me->new_pointer = 0;
}
- CMediaSample_vector_erase(me->free_list,it);
return 0;
}
-static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator * This,
- /* [in] */ IMediaSample *pBuffer)
+static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator* This,
+ /* [in] */ IMediaSample* pBuffer)
{
+ avm_list_t* l;
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)
+ Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This,
+ avm_list_size(me->used_list), avm_list_size(me->free_list));
+
+ l = avm_list_find(me->used_list, pBuffer);
+ if (l)
+ {
+ CMediaSample* sample = (CMediaSample*) l->member;
+ if (me->modified_sample == sample)
{
- CMediaSample_vector_erase(me->used_list,it);
- CMediaSample_vector_push_back(me->free_list,(CMediaSample*)pBuffer);
- return 0;
+ me->modified_sample->ResetPointer(me->modified_sample);
+ me->modified_sample = 0;
}
- Debug printf("Releasing unknown buffer\n");
+ 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("MemAllocator_ReleaseBuffer(%p) releasing unknown buffer!!!! %p\n", This, pBuffer);
return E_FAIL;
}
-MemAllocator * MemAllocator_Create()
+
+static void MemAllocator_SetPointer(MemAllocator* This, char* pointer)
+{
+ This->new_pointer = pointer;
+}
+
+static void MemAllocator_ResetPointer(MemAllocator* This)
{
- 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;
+ if (This->modified_sample)
+ {
+ This->modified_sample->ResetPointer(This->modified_sample);
+ This->modified_sample = 0;
+ }
}
-void MemAllocator_Destroy(MemAllocator *this)
+void MemAllocator_Destroy(MemAllocator* This)
{
- if( --Allocator_Used == 0)
- UnregisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator);
-
- Debug printf("MemAllocator::~MemAllocator() called\n");
- free( this->vt );
+ 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);
+}
+
+IMPLEMENT_IUNKNOWN(MemAllocator)
+
+MemAllocator* MemAllocatorCreate()
+{
+ MemAllocator* This = (MemAllocator*) malloc(sizeof(MemAllocator));
+
+ if (!This)
+ return NULL;
+
+ 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));
+
+ if (!This->vt)
+ {
+ free(This);
+ return NULL;
+ }
+
+ 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->modified_sample = 0;
+ This->new_pointer = 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;
}