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