168
|
1 #include "allocator.h"
|
2069
|
2 #include "com.h"
|
|
3 #include "wine/winerror.h"
|
1545
|
4 #include <stdio.h>
|
|
5
|
|
6 //#undef Debug
|
|
7 //#define Debug
|
|
8
|
713
|
9 using namespace std;
|
|
10
|
168
|
11 class AllocatorKeeper
|
|
12 {
|
|
13 public:
|
|
14 AllocatorKeeper()
|
1545
|
15 {
|
168
|
16 RegisterComClass(&CLSID_MemoryAllocator, MemAllocator::CreateAllocator);
|
|
17 }
|
1545
|
18 ~AllocatorKeeper()
|
|
19 {
|
|
20 UnregisterComClass(&CLSID_MemoryAllocator, MemAllocator::CreateAllocator);
|
|
21 }
|
168
|
22 };
|
|
23 static AllocatorKeeper keeper;
|
1545
|
24
|
|
25
|
168
|
26 GUID MemAllocator::interfaces[]=
|
|
27 {
|
|
28 IID_IUnknown,
|
|
29 IID_IMemAllocator,
|
|
30 };
|
1545
|
31
|
168
|
32 IMPLEMENT_IUNKNOWN(MemAllocator)
|
|
33
|
|
34 long MemAllocator::CreateAllocator(GUID* clsid, GUID* iid, void** ppv)
|
|
35 {
|
|
36 if(!ppv)return -1;
|
|
37 *ppv=0;
|
|
38 if(memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID)))
|
|
39 return -1;
|
1545
|
40
|
168
|
41 IMemAllocator* p=new MemAllocator;
|
|
42 int result=p->vt->QueryInterface((IUnknown*)p, iid, ppv);
|
|
43 p->vt->Release((IUnknown*)p);
|
|
44 return result;
|
|
45 }
|
|
46
|
|
47
|
1545
|
48 static HRESULT STDCALL MemAllocator_SetProperties(IMemAllocator * This,
|
|
49 /* [in] */ ALLOCATOR_PROPERTIES *pRequest,
|
|
50 /* [out] */ ALLOCATOR_PROPERTIES *pActual)
|
168
|
51 {
|
1545
|
52 Debug printf("MemAllocator_SetProperties() called\n");
|
|
53 if (!pRequest || !pActual)
|
|
54 return E_INVALIDARG;
|
|
55 if (pRequest->cBuffers<=0 || pRequest->cbBuffer<=0)
|
|
56 return E_FAIL;
|
|
57 MemAllocator* me = (MemAllocator*)This;
|
|
58 if (me->used_list.size() || me->free_list.size())
|
|
59 return E_FAIL;
|
|
60 me->props = *pRequest;
|
|
61 *pActual = *pRequest;
|
168
|
62 return 0;
|
|
63 }
|
|
64
|
1545
|
65 static HRESULT STDCALL MemAllocator_GetProperties(IMemAllocator * This,
|
|
66 /* [out] */ ALLOCATOR_PROPERTIES *pProps)
|
168
|
67 {
|
1545
|
68 Debug printf("MemAllocator_GetProperties(%p) called\n", This);
|
|
69 if (!pProps)
|
|
70 return E_INVALIDARG;
|
|
71 if (((MemAllocator*)This)->props.cbBuffer<0)
|
|
72 return E_FAIL;
|
168
|
73 *pProps=((MemAllocator*)This)->props;
|
|
74 return 0;
|
|
75 }
|
|
76
|
1545
|
77 static HRESULT STDCALL MemAllocator_Commit(IMemAllocator * This)
|
168
|
78 {
|
1545
|
79 Debug printf("MemAllocator_Commit(%p) called\n", This);
|
168
|
80 MemAllocator* me=(MemAllocator*)This;
|
1545
|
81 if (((MemAllocator*)This)->props.cbBuffer < 0)
|
|
82 return E_FAIL;
|
|
83 if (me->used_list.size() || me->free_list.size())
|
|
84 return E_INVALIDARG;
|
|
85 for(int i = 0; i<me->props.cBuffers; i++)
|
168
|
86 me->free_list.push_back(new CMediaSample(me, me->props.cbBuffer));
|
1545
|
87
|
168
|
88 return 0;
|
|
89 }
|
|
90
|
1545
|
91 static HRESULT STDCALL MemAllocator_Decommit(IMemAllocator * This)
|
168
|
92 {
|
1545
|
93 Debug printf("MemAllocator_Decommit(%p) called\n", This);
|
168
|
94 MemAllocator* me=(MemAllocator*)This;
|
|
95 list<CMediaSample*>::iterator it;
|
|
96 for(it=me->free_list.begin(); it!=me->free_list.end(); it++)
|
|
97 delete *it;
|
|
98 for(it=me->used_list.begin(); it!=me->used_list.end(); it++)
|
|
99 delete *it;
|
|
100 me->free_list.clear();
|
1545
|
101 me->used_list.clear();
|
168
|
102 return 0;
|
|
103 }
|
|
104
|
1545
|
105 static HRESULT STDCALL MemAllocator_GetBuffer(IMemAllocator * This,
|
|
106 /* [out] */ IMediaSample **ppBuffer,
|
|
107 /* [in] */ REFERENCE_TIME *pStartTime,
|
|
108 /* [in] */ REFERENCE_TIME *pEndTime,
|
|
109 /* [in] */ DWORD dwFlags)
|
168
|
110 {
|
1545
|
111 Debug printf("MemAllocator_GetBuffer(%p) called\n", This);
|
|
112 MemAllocator* me = (MemAllocator*)This;
|
|
113 if (me->free_list.size() == 0)
|
168
|
114 {
|
|
115 Debug printf("No samples available\n");
|
1545
|
116 return E_FAIL;//should block here if no samples are available
|
|
117 }
|
|
118 list<CMediaSample*>::iterator it = me->free_list.begin();
|
168
|
119 me->used_list.push_back(*it);
|
1545
|
120 *ppBuffer = *it;
|
168
|
121 (*ppBuffer)->vt->AddRef((IUnknown*)*ppBuffer);
|
1545
|
122 if (me->new_pointer)
|
713
|
123 {
|
|
124 if(me->modified_sample)
|
|
125 me->modified_sample->ResetPointer();
|
1545
|
126 (*it)->SetPointer(me->new_pointer);
|
713
|
127 me->modified_sample=*it;
|
1545
|
128 me->new_pointer = 0;
|
713
|
129 }
|
168
|
130 me->free_list.remove(*it);
|
|
131 return 0;
|
|
132 }
|
|
133
|
1545
|
134 static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator * This,
|
|
135 /* [in] */ IMediaSample *pBuffer)
|
168
|
136 {
|
1545
|
137 Debug printf("MemAllocator_ReleaseBuffer(%p) called\n", This);
|
|
138 MemAllocator* me = (MemAllocator*)This;
|
168
|
139 list<CMediaSample*>::iterator it;
|
1545
|
140 for (it = me->used_list.begin(); it != me->used_list.end(); it++)
|
|
141 if (*it == pBuffer)
|
168
|
142 {
|
|
143 me->used_list.erase(it);
|
|
144 me->free_list.push_back((CMediaSample*)pBuffer);
|
|
145 return 0;
|
|
146 }
|
|
147 Debug printf("Releasing unknown buffer\n");
|
1545
|
148 return E_FAIL;
|
168
|
149 }
|
1545
|
150
|
|
151 MemAllocator::MemAllocator()
|
|
152 {
|
|
153 Debug printf("MemAllocator::MemAllocator() called\n");
|
|
154 vt = new IMemAllocator_vt;
|
|
155 vt->QueryInterface = QueryInterface;
|
|
156 vt->AddRef = AddRef;
|
|
157 vt->Release = Release;
|
|
158 vt->SetProperties = MemAllocator_SetProperties;
|
|
159 vt->GetProperties = MemAllocator_GetProperties;
|
|
160 vt->Commit = MemAllocator_Commit;
|
|
161 vt->Decommit = MemAllocator_Decommit;
|
|
162 vt->GetBuffer = MemAllocator_GetBuffer;
|
|
163 vt->ReleaseBuffer = MemAllocator_ReleaseBuffer;
|
|
164
|
|
165 refcount = 1;
|
|
166 props.cBuffers = 1;
|
|
167 props.cbBuffer = 65536; /* :/ */
|
|
168 props.cbAlign = props.cbPrefix = 0;
|
|
169
|
|
170 new_pointer=0;
|
|
171 modified_sample=0;
|
|
172 }
|
|
173
|
|
174 MemAllocator::~MemAllocator()
|
|
175 {
|
|
176 Debug printf("MemAllocator::~MemAllocator() called\n");
|
|
177 delete vt;
|
|
178 }
|