Mercurial > mplayer.hg
annotate loader/dshow/allocator.c @ 33263:5f527a9a9521
Add an exit function.
This function will allow performing clean-up operations.
(MPlayer calls guiDone() before exiting, but only if the GUI has been
initialized, i.e. if guiInit() has been called successfully. Any
exit_player()/exit_player_with_rc() after GUI's cfg_read() until
guiInit(), or any exit_player() during guiInit() itself will end the GUI
without calling guiDone(). This exit function will at least handle
abortions during guiInit() itself. It will be called twice in case of an
guiExit() after GUI initialization - first directly, next by guiDone()
via MPlayer's exit_player_with_rc().)
author | ib |
---|---|
date | Tue, 03 May 2011 12:19:22 +0000 |
parents | c121d03db8b9 |
children |
rev | line source |
---|---|
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
1 /* |
18783 | 2 * Modified for use with MPlayer, detailed changelog at |
3 * http://svn.mplayerhq.hu/mplayer/trunk/ | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
4 */ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
5 |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
6 #include "config.h" |
168 | 7 #include "allocator.h" |
30170
008338d7679f
Drop -Iloader from CPPFLAGS for the loader subdirectory.
diego
parents:
29263
diff
changeset
|
8 #include "loader/com.h" |
008338d7679f
Drop -Iloader from CPPFLAGS for the loader subdirectory.
diego
parents:
29263
diff
changeset
|
9 #include "loader/wine/winerror.h" |
1545 | 10 #include <stdio.h> |
7386 | 11 #include <stdlib.h> |
1545 | 12 |
3056 | 13 static int AllocatorKeeper = 0; |
1545 | 14 |
25794
2c8cdb9123b8
Fix a ton of illegal identifiers. Identifiers starting with __ or _ and a
diego
parents:
22304
diff
changeset
|
15 struct avm_list_t |
7386 | 16 { |
25794
2c8cdb9123b8
Fix a ton of illegal identifiers. Identifiers starting with __ or _ and a
diego
parents:
22304
diff
changeset
|
17 struct avm_list_t* next; |
2c8cdb9123b8
Fix a ton of illegal identifiers. Identifiers starting with __ or _ and a
diego
parents:
22304
diff
changeset
|
18 struct avm_list_t* prev; |
7386 | 19 void* member; |
20 }; | |
21 | |
3056 | 22 static inline int avm_list_size(avm_list_t* head) |
23 { | |
24 avm_list_t* it = head; | |
25 int i = 0; | |
26 if (it) | |
27 { | |
28 for (;;) | |
29 { | |
30 i++; | |
31 it = it->next; | |
32 if (it == head) | |
33 break; | |
34 } | |
35 } | |
36 return i; | |
37 } | |
713 | 38 |
3056 | 39 static inline int avm_list_print(avm_list_t* head) |
168 | 40 { |
3056 | 41 avm_list_t* it = head; |
42 int i = 0; | |
43 printf("Head: %p\n", head); | |
44 if (it) | |
1545 | 45 { |
3056 | 46 for (;;) |
47 { | |
48 i++; | |
49 printf("%d: member: %p next: %p prev: %p\n", | |
50 i, it->member, it->next, it->prev); | |
51 it = it->next; | |
52 if (it == head) | |
53 break; | |
54 } | |
168 | 55 } |
3056 | 56 return i; |
57 } | |
58 | |
59 static inline avm_list_t* avm_list_add_head(avm_list_t* head, void* member) | |
60 { | |
30702 | 61 avm_list_t* n = malloc(sizeof(avm_list_t)); |
3056 | 62 n->member = member; |
63 | |
64 if (!head) | |
1545 | 65 { |
3056 | 66 head = n; |
67 head->prev = head; | |
1545 | 68 } |
3056 | 69 |
70 n->prev = head->prev; | |
71 head->prev = n; | |
72 n->next = head; | |
73 | |
74 return n; | |
75 } | |
1545 | 76 |
3056 | 77 static inline avm_list_t* avm_list_add_tail(avm_list_t* head, void* member) |
78 { | |
79 avm_list_t* n = avm_list_add_head(head, member); | |
80 return (!head) ? n : head; | |
81 } | |
1545 | 82 |
3056 | 83 static inline avm_list_t* avm_list_del_head(avm_list_t* head) |
168 | 84 { |
3056 | 85 avm_list_t* n = 0; |
3467 | 86 |
3056 | 87 if (head) |
88 { | |
89 if (head->next != head) | |
90 { | |
91 n = head->next; | |
92 head->prev->next = head->next; | |
93 head->next->prev = head->prev; | |
94 } | |
95 free(head); | |
96 } | |
97 return n; | |
98 } | |
168 | 99 |
3056 | 100 static inline avm_list_t* avm_list_find(avm_list_t* head, void* member) |
168 | 101 { |
3056 | 102 avm_list_t* it = head; |
103 if (it) | |
104 { | |
105 for (;;) | |
106 { | |
107 if (it->member == member) | |
108 return it; | |
109 it = it->next; | |
110 if (it == head) | |
111 break; | |
112 } | |
113 } | |
114 return NULL; | |
115 } | |
116 | |
7386 | 117 static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** ppv) |
3056 | 118 { |
30824 | 119 IUnknown* p; |
3056 | 120 int result; |
121 if (!ppv) | |
122 return -1; | |
123 *ppv = 0; | |
124 if (memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID))) | |
168 | 125 return -1; |
1545 | 126 |
30824 | 127 p = (IUnknown*) MemAllocatorCreate(); |
128 result = p->vt->QueryInterface(p, iid, ppv); | |
129 p->vt->Release(p); | |
3056 | 130 |
168 | 131 return result; |
132 } | |
133 | |
1545 | 134 static HRESULT STDCALL MemAllocator_SetProperties(IMemAllocator * This, |
135 /* [in] */ ALLOCATOR_PROPERTIES *pRequest, | |
136 /* [out] */ ALLOCATOR_PROPERTIES *pActual) | |
168 | 137 { |
3056 | 138 MemAllocator* me = (MemAllocator*)This; |
139 Debug printf("MemAllocator_SetProperties(%p) called\n", This); | |
1545 | 140 if (!pRequest || !pActual) |
141 return E_INVALIDARG; | |
142 if (pRequest->cBuffers<=0 || pRequest->cbBuffer<=0) | |
143 return E_FAIL; | |
3056 | 144 if (me->used_list != 0 || me->free_list != 0) |
1545 | 145 return E_FAIL; |
3467 | 146 |
1545 | 147 *pActual = *pRequest; |
22304
254733f57707
Fixed loading of VoxWare and wma9sp binary audio codecs using dshow engine.
voroshil
parents:
18783
diff
changeset
|
148 /* |
254733f57707
Fixed loading of VoxWare and wma9sp binary audio codecs using dshow engine.
voroshil
parents:
18783
diff
changeset
|
149 DirectShow DOCS ("Negotiating Allocators" chapter) says that allocator might not |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25849
diff
changeset
|
150 honor the requested properties. Thus, since WMSP audio codecs requests bufer with two |
22304
254733f57707
Fixed loading of VoxWare and wma9sp binary audio codecs using dshow engine.
voroshil
parents:
18783
diff
changeset
|
151 bytes length for unknown reason, we should correct requested value. Otherwise above |
254733f57707
Fixed loading of VoxWare and wma9sp binary audio codecs using dshow engine.
voroshil
parents:
18783
diff
changeset
|
152 codec don't want to load. |
254733f57707
Fixed loading of VoxWare and wma9sp binary audio codecs using dshow engine.
voroshil
parents:
18783
diff
changeset
|
153 */ |
254733f57707
Fixed loading of VoxWare and wma9sp binary audio codecs using dshow engine.
voroshil
parents:
18783
diff
changeset
|
154 if (pActual->cbBuffer == 2) |
254733f57707
Fixed loading of VoxWare and wma9sp binary audio codecs using dshow engine.
voroshil
parents:
18783
diff
changeset
|
155 pActual->cbBuffer = 10240; //Enough for WMSP codec |
3467 | 156 |
157 me->props = *pActual; | |
3056 | 158 |
168 | 159 return 0; |
160 } | |
161 | |
1545 | 162 static HRESULT STDCALL MemAllocator_GetProperties(IMemAllocator * This, |
163 /* [out] */ ALLOCATOR_PROPERTIES *pProps) | |
168 | 164 { |
1545 | 165 Debug printf("MemAllocator_GetProperties(%p) called\n", This); |
166 if (!pProps) | |
167 return E_INVALIDARG; | |
168 if (((MemAllocator*)This)->props.cbBuffer<0) | |
169 return E_FAIL; | |
168 | 170 *pProps=((MemAllocator*)This)->props; |
3056 | 171 |
168 | 172 return 0; |
173 } | |
174 | |
1545 | 175 static HRESULT STDCALL MemAllocator_Commit(IMemAllocator * This) |
168 | 176 { |
3056 | 177 MemAllocator* me = (MemAllocator*)This; |
178 int i; | |
1545 | 179 Debug printf("MemAllocator_Commit(%p) called\n", This); |
180 if (((MemAllocator*)This)->props.cbBuffer < 0) | |
181 return E_FAIL; | |
3056 | 182 if (me->used_list || me->free_list) |
1545 | 183 return E_INVALIDARG; |
3056 | 184 for (i = 0; i < me->props.cBuffers; i++) |
185 { | |
186 CMediaSample* sample = CMediaSampleCreate((IMemAllocator*)me, | |
187 me->props.cbBuffer); | |
3467 | 188 if (!sample) |
189 return E_OUTOFMEMORY; | |
3056 | 190 //printf("FREEEEEEEEEEEE ADDED %p\n", sample); |
191 me->free_list = avm_list_add_tail(me->free_list, sample); | |
192 //avm_list_print(me->free_list); | |
193 } | |
194 | |
195 //printf("Added mem %p: lsz: %d %d size: %d\n", me, avm_list_size(me->free_list), me->props.cBuffers, me->props.cbBuffer); | |
168 | 196 return 0; |
197 } | |
198 | |
1545 | 199 static HRESULT STDCALL MemAllocator_Decommit(IMemAllocator * This) |
168 | 200 { |
3056 | 201 MemAllocator* me=(MemAllocator*)This; |
1545 | 202 Debug printf("MemAllocator_Decommit(%p) called\n", This); |
3056 | 203 //printf("Deleted mem %p: %d %d\n", me, me->free_list.size(), me->used_list.size()); |
204 while (me->used_list) | |
205 { | |
3467 | 206 me->free_list = avm_list_add_tail(me->free_list, |
207 (CMediaSample*) me->used_list->member); | |
3056 | 208 me->used_list = avm_list_del_head(me->used_list); |
209 } | |
210 | |
211 while (me->free_list) | |
212 { | |
213 CMediaSample* sample = (CMediaSample*) me->free_list->member; | |
214 //printf("****************** Decommiting FREE %p\n", sample); | |
215 //sample->vt->Release((IUnknown*)sample); | |
216 CMediaSample_Destroy((CMediaSample*)sample); | |
3467 | 217 me->free_list = avm_list_del_head(me->free_list); |
3056 | 218 } |
219 | |
168 | 220 return 0; |
221 } | |
222 | |
1545 | 223 static HRESULT STDCALL MemAllocator_GetBuffer(IMemAllocator * This, |
224 /* [out] */ IMediaSample **ppBuffer, | |
225 /* [in] */ REFERENCE_TIME *pStartTime, | |
226 /* [in] */ REFERENCE_TIME *pEndTime, | |
227 /* [in] */ DWORD dwFlags) | |
168 | 228 { |
1545 | 229 MemAllocator* me = (MemAllocator*)This; |
3056 | 230 CMediaSample* sample; |
3467 | 231 Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This, |
3056 | 232 avm_list_size(me->used_list), avm_list_size(me->free_list)); |
3467 | 233 |
3056 | 234 if (!me->free_list) |
168 | 235 { |
236 Debug printf("No samples available\n"); | |
1545 | 237 return E_FAIL;//should block here if no samples are available |
238 } | |
3056 | 239 |
240 sample = (CMediaSample*) me->free_list->member; | |
241 me->free_list = avm_list_del_head(me->free_list); | |
242 me->used_list = avm_list_add_tail(me->used_list, sample); | |
243 | |
244 *ppBuffer = (IMediaSample*) sample; | |
245 sample->vt->AddRef((IUnknown*) sample); | |
1545 | 246 if (me->new_pointer) |
713 | 247 { |
3056 | 248 if (me->modified_sample) |
249 me->modified_sample->ResetPointer(me->modified_sample); | |
250 sample->SetPointer(sample, me->new_pointer); | |
251 me->modified_sample = sample; | |
1545 | 252 me->new_pointer = 0; |
713 | 253 } |
168 | 254 return 0; |
255 } | |
256 | |
3056 | 257 static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator* This, |
258 /* [in] */ IMediaSample* pBuffer) | |
168 | 259 { |
3467 | 260 avm_list_t* l; |
1545 | 261 MemAllocator* me = (MemAllocator*)This; |
3056 | 262 Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This, |
263 avm_list_size(me->used_list), avm_list_size(me->free_list)); | |
264 | |
3467 | 265 l = avm_list_find(me->used_list, pBuffer); |
266 if (l) | |
3056 | 267 { |
3467 | 268 CMediaSample* sample = (CMediaSample*) l->member; |
269 if (me->modified_sample == sample) | |
168 | 270 { |
3467 | 271 me->modified_sample->ResetPointer(me->modified_sample); |
272 me->modified_sample = 0; | |
168 | 273 } |
3467 | 274 me->used_list = avm_list_del_head(me->used_list); |
275 me->free_list = avm_list_add_head(me->free_list, sample); | |
276 //printf("****************** RELEASED OK %p %p\n", me->used_list, me->free_list); | |
277 return 0; | |
3056 | 278 } |
279 Debug printf("MemAllocator_ReleaseBuffer(%p) releasing unknown buffer!!!! %p\n", This, pBuffer); | |
1545 | 280 return E_FAIL; |
168 | 281 } |
1545 | 282 |
3056 | 283 |
284 static void MemAllocator_SetPointer(MemAllocator* This, char* pointer) | |
285 { | |
286 This->new_pointer = pointer; | |
287 } | |
288 | |
289 static void MemAllocator_ResetPointer(MemAllocator* This) | |
1545 | 290 { |
3056 | 291 if (This->modified_sample) |
292 { | |
293 This->modified_sample->ResetPointer(This->modified_sample); | |
294 This->modified_sample = 0; | |
295 } | |
296 } | |
1545 | 297 |
8292 | 298 static void MemAllocator_Destroy(MemAllocator* This) |
3056 | 299 { |
300 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
|
301 #ifdef WIN32_LOADER |
3056 | 302 if (--AllocatorKeeper == 0) |
303 UnregisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator); | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
304 #endif |
3056 | 305 free(This->vt); |
306 free(This); | |
1545 | 307 } |
308 | |
3056 | 309 IMPLEMENT_IUNKNOWN(MemAllocator) |
310 | |
311 MemAllocator* MemAllocatorCreate() | |
1545 | 312 { |
30702 | 313 MemAllocator* This = malloc(sizeof(MemAllocator)); |
3467 | 314 |
315 if (!This) | |
316 return NULL; | |
317 | |
3056 | 318 Debug printf("MemAllocatorCreate() called -> %p\n", This); |
319 | |
320 This->refcount = 1; | |
321 This->props.cBuffers = 1; | |
322 This->props.cbBuffer = 65536; /* :/ */ | |
9503
f47d484d8f28
cbAlign=1 fix for proper Windows support (noticed by Sascha Sommer)
alex
parents:
8292
diff
changeset
|
323 This->props.cbAlign = 1; |
f47d484d8f28
cbAlign=1 fix for proper Windows support (noticed by Sascha Sommer)
alex
parents:
8292
diff
changeset
|
324 This->props.cbPrefix = 0; |
3056 | 325 |
30702 | 326 This->vt = malloc(sizeof(IMemAllocator_vt)); |
3467 | 327 |
328 if (!This->vt) | |
329 { | |
330 free(This); | |
331 return NULL; | |
332 } | |
333 | |
3056 | 334 This->vt->QueryInterface = MemAllocator_QueryInterface; |
335 This->vt->AddRef = MemAllocator_AddRef; | |
336 This->vt->Release = MemAllocator_Release; | |
337 This->vt->SetProperties = MemAllocator_SetProperties; | |
338 This->vt->GetProperties = MemAllocator_GetProperties; | |
339 This->vt->Commit = MemAllocator_Commit; | |
340 This->vt->Decommit = MemAllocator_Decommit; | |
341 This->vt->GetBuffer = MemAllocator_GetBuffer; | |
342 This->vt->ReleaseBuffer = MemAllocator_ReleaseBuffer; | |
343 | |
344 This->SetPointer = MemAllocator_SetPointer; | |
345 This->ResetPointer = MemAllocator_ResetPointer; | |
346 | |
3467 | 347 This->modified_sample = 0; |
3056 | 348 This->new_pointer = 0; |
349 This->used_list = 0; | |
350 This->free_list = 0; | |
351 | |
352 This->interfaces[0]=IID_IUnknown; | |
353 This->interfaces[1]=IID_IMemAllocator; | |
354 | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
355 #ifdef WIN32_LOADER |
3056 | 356 if (AllocatorKeeper++ == 0) |
357 RegisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator); | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
358 #endif |
3056 | 359 |
360 return This; | |
1545 | 361 } |