⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 allocator.c

📁 linux下的MPEG1
💻 C
字号:
#include "allocator.h"#include "com.h"#include "../wine/winerror.h"#include <stdio.h>#include <stdlib.h>static int AllocatorKeeper = 0;struct _avm_list_t{    struct _avm_list_t* next;    struct _avm_list_t* prev;    void* member;};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;}static inline int avm_list_print(avm_list_t* head){    avm_list_t* it = head;    int i = 0;    printf("Head: %p\n", head);    if (it)    {	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;	}    }    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)    {	head = n;        head->prev = head;    }    n->prev = head->prev;    head->prev = n;    n->next = head;    return n;}static inline avm_list_t* avm_list_add_tail(avm_list_t* head, void* member){    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)	{	    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;}static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** ppv){    IMemAllocator* p;    int result;    if (!ppv)	return -1;    *ppv = 0;    if (memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID)))	return -1;    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){    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;    if (me->used_list != 0 || me->free_list != 0)	return E_FAIL;    *pActual = *pRequest;    //if (pActual->cbBuffer == 2)    //    pActual->cbBuffer = 576;    me->props = *pActual;    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){    MemAllocator* me = (MemAllocator*)This;    int i;    Debug printf("MemAllocator_Commit(%p) called\n", This);    if (((MemAllocator*)This)->props.cbBuffer < 0)	return E_FAIL;    if (me->used_list || me->free_list)	return E_INVALIDARG;    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: 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;    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)    {	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;}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* 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    }    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)	    me->modified_sample->ResetPointer(me->modified_sample);	sample->SetPointer(sample, me->new_pointer);	me->modified_sample = sample;	me->new_pointer = 0;    }    return 0;}static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator* This,						  /* [in] */ IMediaSample* pBuffer){    avm_list_t* l;    MemAllocator* me = (MemAllocator*)This;    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)	{	    me->modified_sample->ResetPointer(me->modified_sample);	    me->modified_sample = 0;	}	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;}static void MemAllocator_SetPointer(MemAllocator* This, char* pointer){    This->new_pointer = pointer;}static void MemAllocator_ResetPointer(MemAllocator* This){    if (This->modified_sample)    {	This->modified_sample->ResetPointer(This->modified_sample);	This->modified_sample = 0;    }}static 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);}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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -