Mercurial > mplayer.hg
annotate loader/dshow/allocator.c @ 9840:2a219cbb1435
Chinese translation for main branch
author | luran |
---|---|
date | Sun, 06 Apr 2003 13:27:10 +0000 |
parents | f47d484d8f28 |
children | b0d1b415320c |
rev | line source |
---|---|
168 | 1 #include "allocator.h" |
2069 | 2 #include "com.h" |
3 #include "wine/winerror.h" | |
1545 | 4 #include <stdio.h> |
7386 | 5 #include <stdlib.h> |
1545 | 6 |
3056 | 7 static int AllocatorKeeper = 0; |
1545 | 8 |
7386 | 9 struct _avm_list_t |
10 { | |
11 struct _avm_list_t* next; | |
12 struct _avm_list_t* prev; | |
13 void* member; | |
14 }; | |
15 | |
3056 | 16 static inline int avm_list_size(avm_list_t* head) |
17 { | |
18 avm_list_t* it = head; | |
19 int i = 0; | |
20 if (it) | |
21 { | |
22 for (;;) | |
23 { | |
24 i++; | |
25 it = it->next; | |
26 if (it == head) | |
27 break; | |
28 } | |
29 } | |
30 return i; | |
31 } | |
713 | 32 |
3056 | 33 static inline int avm_list_print(avm_list_t* head) |
168 | 34 { |
3056 | 35 avm_list_t* it = head; |
36 int i = 0; | |
37 printf("Head: %p\n", head); | |
38 if (it) | |
1545 | 39 { |
3056 | 40 for (;;) |
41 { | |
42 i++; | |
43 printf("%d: member: %p next: %p prev: %p\n", | |
44 i, it->member, it->next, it->prev); | |
45 it = it->next; | |
46 if (it == head) | |
47 break; | |
48 } | |
168 | 49 } |
3056 | 50 return i; |
51 } | |
52 | |
53 static inline avm_list_t* avm_list_add_head(avm_list_t* head, void* member) | |
54 { | |
55 avm_list_t* n = (avm_list_t*) malloc(sizeof(avm_list_t)); | |
56 n->member = member; | |
57 | |
58 if (!head) | |
1545 | 59 { |
3056 | 60 head = n; |
61 head->prev = head; | |
1545 | 62 } |
3056 | 63 |
64 n->prev = head->prev; | |
65 head->prev = n; | |
66 n->next = head; | |
67 | |
68 return n; | |
69 } | |
1545 | 70 |
3056 | 71 static inline avm_list_t* avm_list_add_tail(avm_list_t* head, void* member) |
72 { | |
73 avm_list_t* n = avm_list_add_head(head, member); | |
74 return (!head) ? n : head; | |
75 } | |
1545 | 76 |
3056 | 77 static inline avm_list_t* avm_list_del_head(avm_list_t* head) |
168 | 78 { |
3056 | 79 avm_list_t* n = 0; |
3467 | 80 |
3056 | 81 if (head) |
82 { | |
83 if (head->next != head) | |
84 { | |
85 n = head->next; | |
86 head->prev->next = head->next; | |
87 head->next->prev = head->prev; | |
88 } | |
89 free(head); | |
90 } | |
91 return n; | |
92 } | |
168 | 93 |
3056 | 94 static inline avm_list_t* avm_list_find(avm_list_t* head, void* member) |
168 | 95 { |
3056 | 96 avm_list_t* it = head; |
97 if (it) | |
98 { | |
99 for (;;) | |
100 { | |
101 if (it->member == member) | |
102 return it; | |
103 it = it->next; | |
104 if (it == head) | |
105 break; | |
106 } | |
107 } | |
108 return NULL; | |
109 } | |
110 | |
7386 | 111 static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** ppv) |
3056 | 112 { |
113 IMemAllocator* p; | |
114 int result; | |
115 if (!ppv) | |
116 return -1; | |
117 *ppv = 0; | |
118 if (memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID))) | |
168 | 119 return -1; |
1545 | 120 |
3056 | 121 p = (IMemAllocator*) MemAllocatorCreate(); |
122 result = p->vt->QueryInterface((IUnknown*)p, iid, ppv); | |
168 | 123 p->vt->Release((IUnknown*)p); |
3056 | 124 |
168 | 125 return result; |
126 } | |
127 | |
1545 | 128 static HRESULT STDCALL MemAllocator_SetProperties(IMemAllocator * This, |
129 /* [in] */ ALLOCATOR_PROPERTIES *pRequest, | |
130 /* [out] */ ALLOCATOR_PROPERTIES *pActual) | |
168 | 131 { |
3056 | 132 MemAllocator* me = (MemAllocator*)This; |
133 Debug printf("MemAllocator_SetProperties(%p) called\n", This); | |
1545 | 134 if (!pRequest || !pActual) |
135 return E_INVALIDARG; | |
136 if (pRequest->cBuffers<=0 || pRequest->cbBuffer<=0) | |
137 return E_FAIL; | |
3056 | 138 if (me->used_list != 0 || me->free_list != 0) |
1545 | 139 return E_FAIL; |
3467 | 140 |
1545 | 141 *pActual = *pRequest; |
3467 | 142 //if (pActual->cbBuffer == 2) |
143 // pActual->cbBuffer = 576; | |
144 | |
145 me->props = *pActual; | |
3056 | 146 |
168 | 147 return 0; |
148 } | |
149 | |
1545 | 150 static HRESULT STDCALL MemAllocator_GetProperties(IMemAllocator * This, |
151 /* [out] */ ALLOCATOR_PROPERTIES *pProps) | |
168 | 152 { |
1545 | 153 Debug printf("MemAllocator_GetProperties(%p) called\n", This); |
154 if (!pProps) | |
155 return E_INVALIDARG; | |
156 if (((MemAllocator*)This)->props.cbBuffer<0) | |
157 return E_FAIL; | |
168 | 158 *pProps=((MemAllocator*)This)->props; |
3056 | 159 |
168 | 160 return 0; |
161 } | |
162 | |
1545 | 163 static HRESULT STDCALL MemAllocator_Commit(IMemAllocator * This) |
168 | 164 { |
3056 | 165 MemAllocator* me = (MemAllocator*)This; |
166 int i; | |
1545 | 167 Debug printf("MemAllocator_Commit(%p) called\n", This); |
168 if (((MemAllocator*)This)->props.cbBuffer < 0) | |
169 return E_FAIL; | |
3056 | 170 if (me->used_list || me->free_list) |
1545 | 171 return E_INVALIDARG; |
3056 | 172 for (i = 0; i < me->props.cBuffers; i++) |
173 { | |
174 CMediaSample* sample = CMediaSampleCreate((IMemAllocator*)me, | |
175 me->props.cbBuffer); | |
3467 | 176 if (!sample) |
177 return E_OUTOFMEMORY; | |
3056 | 178 //printf("FREEEEEEEEEEEE ADDED %p\n", sample); |
179 me->free_list = avm_list_add_tail(me->free_list, sample); | |
180 //avm_list_print(me->free_list); | |
181 } | |
182 | |
183 //printf("Added mem %p: lsz: %d %d size: %d\n", me, avm_list_size(me->free_list), me->props.cBuffers, me->props.cbBuffer); | |
168 | 184 return 0; |
185 } | |
186 | |
1545 | 187 static HRESULT STDCALL MemAllocator_Decommit(IMemAllocator * This) |
168 | 188 { |
3056 | 189 MemAllocator* me=(MemAllocator*)This; |
1545 | 190 Debug printf("MemAllocator_Decommit(%p) called\n", This); |
3056 | 191 //printf("Deleted mem %p: %d %d\n", me, me->free_list.size(), me->used_list.size()); |
192 while (me->used_list) | |
193 { | |
3467 | 194 me->free_list = avm_list_add_tail(me->free_list, |
195 (CMediaSample*) me->used_list->member); | |
3056 | 196 me->used_list = avm_list_del_head(me->used_list); |
197 } | |
198 | |
199 while (me->free_list) | |
200 { | |
201 CMediaSample* sample = (CMediaSample*) me->free_list->member; | |
202 //printf("****************** Decommiting FREE %p\n", sample); | |
203 //sample->vt->Release((IUnknown*)sample); | |
204 CMediaSample_Destroy((CMediaSample*)sample); | |
3467 | 205 me->free_list = avm_list_del_head(me->free_list); |
3056 | 206 } |
207 | |
168 | 208 return 0; |
209 } | |
210 | |
1545 | 211 static HRESULT STDCALL MemAllocator_GetBuffer(IMemAllocator * This, |
212 /* [out] */ IMediaSample **ppBuffer, | |
213 /* [in] */ REFERENCE_TIME *pStartTime, | |
214 /* [in] */ REFERENCE_TIME *pEndTime, | |
215 /* [in] */ DWORD dwFlags) | |
168 | 216 { |
1545 | 217 MemAllocator* me = (MemAllocator*)This; |
3056 | 218 CMediaSample* sample; |
3467 | 219 Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This, |
3056 | 220 avm_list_size(me->used_list), avm_list_size(me->free_list)); |
3467 | 221 |
3056 | 222 if (!me->free_list) |
168 | 223 { |
224 Debug printf("No samples available\n"); | |
1545 | 225 return E_FAIL;//should block here if no samples are available |
226 } | |
3056 | 227 |
228 sample = (CMediaSample*) me->free_list->member; | |
229 me->free_list = avm_list_del_head(me->free_list); | |
230 me->used_list = avm_list_add_tail(me->used_list, sample); | |
231 | |
232 *ppBuffer = (IMediaSample*) sample; | |
233 sample->vt->AddRef((IUnknown*) sample); | |
1545 | 234 if (me->new_pointer) |
713 | 235 { |
3056 | 236 if (me->modified_sample) |
237 me->modified_sample->ResetPointer(me->modified_sample); | |
238 sample->SetPointer(sample, me->new_pointer); | |
239 me->modified_sample = sample; | |
1545 | 240 me->new_pointer = 0; |
713 | 241 } |
168 | 242 return 0; |
243 } | |
244 | |
3056 | 245 static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator* This, |
246 /* [in] */ IMediaSample* pBuffer) | |
168 | 247 { |
3467 | 248 avm_list_t* l; |
1545 | 249 MemAllocator* me = (MemAllocator*)This; |
3056 | 250 Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This, |
251 avm_list_size(me->used_list), avm_list_size(me->free_list)); | |
252 | |
3467 | 253 l = avm_list_find(me->used_list, pBuffer); |
254 if (l) | |
3056 | 255 { |
3467 | 256 CMediaSample* sample = (CMediaSample*) l->member; |
257 if (me->modified_sample == sample) | |
168 | 258 { |
3467 | 259 me->modified_sample->ResetPointer(me->modified_sample); |
260 me->modified_sample = 0; | |
168 | 261 } |
3467 | 262 me->used_list = avm_list_del_head(me->used_list); |
263 me->free_list = avm_list_add_head(me->free_list, sample); | |
264 //printf("****************** RELEASED OK %p %p\n", me->used_list, me->free_list); | |
265 return 0; | |
3056 | 266 } |
267 Debug printf("MemAllocator_ReleaseBuffer(%p) releasing unknown buffer!!!! %p\n", This, pBuffer); | |
1545 | 268 return E_FAIL; |
168 | 269 } |
1545 | 270 |
3056 | 271 |
272 static void MemAllocator_SetPointer(MemAllocator* This, char* pointer) | |
273 { | |
274 This->new_pointer = pointer; | |
275 } | |
276 | |
277 static void MemAllocator_ResetPointer(MemAllocator* This) | |
1545 | 278 { |
3056 | 279 if (This->modified_sample) |
280 { | |
281 This->modified_sample->ResetPointer(This->modified_sample); | |
282 This->modified_sample = 0; | |
283 } | |
284 } | |
1545 | 285 |
8292 | 286 static void MemAllocator_Destroy(MemAllocator* This) |
3056 | 287 { |
288 Debug printf("MemAllocator_Destroy(%p) called (%d, %d)\n", This, This->refcount, AllocatorKeeper); | |
289 if (--AllocatorKeeper == 0) | |
290 UnregisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator); | |
291 free(This->vt); | |
292 free(This); | |
1545 | 293 } |
294 | |
3056 | 295 IMPLEMENT_IUNKNOWN(MemAllocator) |
296 | |
297 MemAllocator* MemAllocatorCreate() | |
1545 | 298 { |
3056 | 299 MemAllocator* This = (MemAllocator*) malloc(sizeof(MemAllocator)); |
3467 | 300 |
301 if (!This) | |
302 return NULL; | |
303 | |
3056 | 304 Debug printf("MemAllocatorCreate() called -> %p\n", This); |
305 | |
306 This->refcount = 1; | |
307 This->props.cBuffers = 1; | |
308 This->props.cbBuffer = 65536; /* :/ */ | |
9503
f47d484d8f28
cbAlign=1 fix for proper Windows support (noticed by Sascha Sommer)
alex
parents:
8292
diff
changeset
|
309 This->props.cbAlign = 1; |
f47d484d8f28
cbAlign=1 fix for proper Windows support (noticed by Sascha Sommer)
alex
parents:
8292
diff
changeset
|
310 This->props.cbPrefix = 0; |
3056 | 311 |
312 This->vt = (IMemAllocator_vt*) malloc(sizeof(IMemAllocator_vt)); | |
3467 | 313 |
314 if (!This->vt) | |
315 { | |
316 free(This); | |
317 return NULL; | |
318 } | |
319 | |
3056 | 320 This->vt->QueryInterface = MemAllocator_QueryInterface; |
321 This->vt->AddRef = MemAllocator_AddRef; | |
322 This->vt->Release = MemAllocator_Release; | |
323 This->vt->SetProperties = MemAllocator_SetProperties; | |
324 This->vt->GetProperties = MemAllocator_GetProperties; | |
325 This->vt->Commit = MemAllocator_Commit; | |
326 This->vt->Decommit = MemAllocator_Decommit; | |
327 This->vt->GetBuffer = MemAllocator_GetBuffer; | |
328 This->vt->ReleaseBuffer = MemAllocator_ReleaseBuffer; | |
329 | |
330 This->SetPointer = MemAllocator_SetPointer; | |
331 This->ResetPointer = MemAllocator_ResetPointer; | |
332 | |
3467 | 333 This->modified_sample = 0; |
3056 | 334 This->new_pointer = 0; |
335 This->used_list = 0; | |
336 This->free_list = 0; | |
337 | |
338 This->interfaces[0]=IID_IUnknown; | |
339 This->interfaces[1]=IID_IMemAllocator; | |
340 | |
341 if (AllocatorKeeper++ == 0) | |
342 RegisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator); | |
343 | |
344 return This; | |
1545 | 345 } |