Mercurial > mplayer.hg
annotate loader/dshow/allocator.c @ 34507:582ca9169495
Fix 32-bit png playback with current FFmpeg.
author | cehoyos |
---|---|
date | Tue, 24 Jan 2012 18:11:10 +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 } |