Mercurial > mplayer.hg
annotate loader/dshow/allocator.c @ 15533:ddf15d233d58
Do not switch to audio tracks whose codec private data differs from the main audio track's as this will most likely result in messed up audio output. Patch by Michael Behrisch <list () behrisch ! de>
author | mosu |
---|---|
date | Sat, 21 May 2005 06:50:08 +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 } |