Mercurial > mplayer.hg
annotate loader/dshow/allocator.c @ 17590:2fd66535616a
muxer_mpeg MUST be used with audio_preload=0
author | nicodvb |
---|---|
date | Sat, 11 Feb 2006 21:29:03 +0000 |
parents | f5537cc95b02 |
children | 0783dd397f74 |
rev | line source |
---|---|
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
1 /* |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
2 * Modified for use with MPlayer, detailed CVS changelog at |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
3 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ |
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; |
3467 | 149 //if (pActual->cbBuffer == 2) |
150 // pActual->cbBuffer = 576; | |
151 | |
152 me->props = *pActual; | |
3056 | 153 |
168 | 154 return 0; |
155 } | |
156 | |
1545 | 157 static HRESULT STDCALL MemAllocator_GetProperties(IMemAllocator * This, |
158 /* [out] */ ALLOCATOR_PROPERTIES *pProps) | |
168 | 159 { |
1545 | 160 Debug printf("MemAllocator_GetProperties(%p) called\n", This); |
161 if (!pProps) | |
162 return E_INVALIDARG; | |
163 if (((MemAllocator*)This)->props.cbBuffer<0) | |
164 return E_FAIL; | |
168 | 165 *pProps=((MemAllocator*)This)->props; |
3056 | 166 |
168 | 167 return 0; |
168 } | |
169 | |
1545 | 170 static HRESULT STDCALL MemAllocator_Commit(IMemAllocator * This) |
168 | 171 { |
3056 | 172 MemAllocator* me = (MemAllocator*)This; |
173 int i; | |
1545 | 174 Debug printf("MemAllocator_Commit(%p) called\n", This); |
175 if (((MemAllocator*)This)->props.cbBuffer < 0) | |
176 return E_FAIL; | |
3056 | 177 if (me->used_list || me->free_list) |
1545 | 178 return E_INVALIDARG; |
3056 | 179 for (i = 0; i < me->props.cBuffers; i++) |
180 { | |
181 CMediaSample* sample = CMediaSampleCreate((IMemAllocator*)me, | |
182 me->props.cbBuffer); | |
3467 | 183 if (!sample) |
184 return E_OUTOFMEMORY; | |
3056 | 185 //printf("FREEEEEEEEEEEE ADDED %p\n", sample); |
186 me->free_list = avm_list_add_tail(me->free_list, sample); | |
187 //avm_list_print(me->free_list); | |
188 } | |
189 | |
190 //printf("Added mem %p: lsz: %d %d size: %d\n", me, avm_list_size(me->free_list), me->props.cBuffers, me->props.cbBuffer); | |
168 | 191 return 0; |
192 } | |
193 | |
1545 | 194 static HRESULT STDCALL MemAllocator_Decommit(IMemAllocator * This) |
168 | 195 { |
3056 | 196 MemAllocator* me=(MemAllocator*)This; |
1545 | 197 Debug printf("MemAllocator_Decommit(%p) called\n", This); |
3056 | 198 //printf("Deleted mem %p: %d %d\n", me, me->free_list.size(), me->used_list.size()); |
199 while (me->used_list) | |
200 { | |
3467 | 201 me->free_list = avm_list_add_tail(me->free_list, |
202 (CMediaSample*) me->used_list->member); | |
3056 | 203 me->used_list = avm_list_del_head(me->used_list); |
204 } | |
205 | |
206 while (me->free_list) | |
207 { | |
208 CMediaSample* sample = (CMediaSample*) me->free_list->member; | |
209 //printf("****************** Decommiting FREE %p\n", sample); | |
210 //sample->vt->Release((IUnknown*)sample); | |
211 CMediaSample_Destroy((CMediaSample*)sample); | |
3467 | 212 me->free_list = avm_list_del_head(me->free_list); |
3056 | 213 } |
214 | |
168 | 215 return 0; |
216 } | |
217 | |
1545 | 218 static HRESULT STDCALL MemAllocator_GetBuffer(IMemAllocator * This, |
219 /* [out] */ IMediaSample **ppBuffer, | |
220 /* [in] */ REFERENCE_TIME *pStartTime, | |
221 /* [in] */ REFERENCE_TIME *pEndTime, | |
222 /* [in] */ DWORD dwFlags) | |
168 | 223 { |
1545 | 224 MemAllocator* me = (MemAllocator*)This; |
3056 | 225 CMediaSample* sample; |
3467 | 226 Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This, |
3056 | 227 avm_list_size(me->used_list), avm_list_size(me->free_list)); |
3467 | 228 |
3056 | 229 if (!me->free_list) |
168 | 230 { |
231 Debug printf("No samples available\n"); | |
1545 | 232 return E_FAIL;//should block here if no samples are available |
233 } | |
3056 | 234 |
235 sample = (CMediaSample*) me->free_list->member; | |
236 me->free_list = avm_list_del_head(me->free_list); | |
237 me->used_list = avm_list_add_tail(me->used_list, sample); | |
238 | |
239 *ppBuffer = (IMediaSample*) sample; | |
240 sample->vt->AddRef((IUnknown*) sample); | |
1545 | 241 if (me->new_pointer) |
713 | 242 { |
3056 | 243 if (me->modified_sample) |
244 me->modified_sample->ResetPointer(me->modified_sample); | |
245 sample->SetPointer(sample, me->new_pointer); | |
246 me->modified_sample = sample; | |
1545 | 247 me->new_pointer = 0; |
713 | 248 } |
168 | 249 return 0; |
250 } | |
251 | |
3056 | 252 static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator* This, |
253 /* [in] */ IMediaSample* pBuffer) | |
168 | 254 { |
3467 | 255 avm_list_t* l; |
1545 | 256 MemAllocator* me = (MemAllocator*)This; |
3056 | 257 Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This, |
258 avm_list_size(me->used_list), avm_list_size(me->free_list)); | |
259 | |
3467 | 260 l = avm_list_find(me->used_list, pBuffer); |
261 if (l) | |
3056 | 262 { |
3467 | 263 CMediaSample* sample = (CMediaSample*) l->member; |
264 if (me->modified_sample == sample) | |
168 | 265 { |
3467 | 266 me->modified_sample->ResetPointer(me->modified_sample); |
267 me->modified_sample = 0; | |
168 | 268 } |
3467 | 269 me->used_list = avm_list_del_head(me->used_list); |
270 me->free_list = avm_list_add_head(me->free_list, sample); | |
271 //printf("****************** RELEASED OK %p %p\n", me->used_list, me->free_list); | |
272 return 0; | |
3056 | 273 } |
274 Debug printf("MemAllocator_ReleaseBuffer(%p) releasing unknown buffer!!!! %p\n", This, pBuffer); | |
1545 | 275 return E_FAIL; |
168 | 276 } |
1545 | 277 |
3056 | 278 |
279 static void MemAllocator_SetPointer(MemAllocator* This, char* pointer) | |
280 { | |
281 This->new_pointer = pointer; | |
282 } | |
283 | |
284 static void MemAllocator_ResetPointer(MemAllocator* This) | |
1545 | 285 { |
3056 | 286 if (This->modified_sample) |
287 { | |
288 This->modified_sample->ResetPointer(This->modified_sample); | |
289 This->modified_sample = 0; | |
290 } | |
291 } | |
1545 | 292 |
8292 | 293 static void MemAllocator_Destroy(MemAllocator* This) |
3056 | 294 { |
295 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
|
296 #ifdef WIN32_LOADER |
3056 | 297 if (--AllocatorKeeper == 0) |
298 UnregisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator); | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
299 #endif |
3056 | 300 free(This->vt); |
301 free(This); | |
1545 | 302 } |
303 | |
3056 | 304 IMPLEMENT_IUNKNOWN(MemAllocator) |
305 | |
306 MemAllocator* MemAllocatorCreate() | |
1545 | 307 { |
3056 | 308 MemAllocator* This = (MemAllocator*) malloc(sizeof(MemAllocator)); |
3467 | 309 |
310 if (!This) | |
311 return NULL; | |
312 | |
3056 | 313 Debug printf("MemAllocatorCreate() called -> %p\n", This); |
314 | |
315 This->refcount = 1; | |
316 This->props.cBuffers = 1; | |
317 This->props.cbBuffer = 65536; /* :/ */ | |
9503
f47d484d8f28
cbAlign=1 fix for proper Windows support (noticed by Sascha Sommer)
alex
parents:
8292
diff
changeset
|
318 This->props.cbAlign = 1; |
f47d484d8f28
cbAlign=1 fix for proper Windows support (noticed by Sascha Sommer)
alex
parents:
8292
diff
changeset
|
319 This->props.cbPrefix = 0; |
3056 | 320 |
321 This->vt = (IMemAllocator_vt*) malloc(sizeof(IMemAllocator_vt)); | |
3467 | 322 |
323 if (!This->vt) | |
324 { | |
325 free(This); | |
326 return NULL; | |
327 } | |
328 | |
3056 | 329 This->vt->QueryInterface = MemAllocator_QueryInterface; |
330 This->vt->AddRef = MemAllocator_AddRef; | |
331 This->vt->Release = MemAllocator_Release; | |
332 This->vt->SetProperties = MemAllocator_SetProperties; | |
333 This->vt->GetProperties = MemAllocator_GetProperties; | |
334 This->vt->Commit = MemAllocator_Commit; | |
335 This->vt->Decommit = MemAllocator_Decommit; | |
336 This->vt->GetBuffer = MemAllocator_GetBuffer; | |
337 This->vt->ReleaseBuffer = MemAllocator_ReleaseBuffer; | |
338 | |
339 This->SetPointer = MemAllocator_SetPointer; | |
340 This->ResetPointer = MemAllocator_ResetPointer; | |
341 | |
3467 | 342 This->modified_sample = 0; |
3056 | 343 This->new_pointer = 0; |
344 This->used_list = 0; | |
345 This->free_list = 0; | |
346 | |
347 This->interfaces[0]=IID_IUnknown; | |
348 This->interfaces[1]=IID_IMemAllocator; | |
349 | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
350 #ifdef WIN32_LOADER |
3056 | 351 if (AllocatorKeeper++ == 0) |
352 RegisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator); | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
353 #endif |
3056 | 354 |
355 return This; | |
1545 | 356 } |