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