diff options
Diffstat (limited to 'src/libw32dll/DirectShow/allocator.c')
-rw-r--r-- | src/libw32dll/DirectShow/allocator.c | 419 |
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; } |