Mercurial > mplayer.hg
annotate tremor/block.c @ 30811:50e0f6942e43
Implement Win32 mutexes.
Implement Win32 mutexes; they used to just be mapped on top of events, which
is not the same thing at all.
The implementation is pretty much the obvious one, similar to the
current critical section implementation and the semaphore implementation;
a single lock count protected by a pthread mutex, and an event lockers can
sleep on to know when the mutex is available.
Also make CreateMutexA and ReleaseMutex available even if QuickTime codecs
support is not configured.
author | sesse |
---|---|
date | Sat, 06 Mar 2010 10:13:37 +0000 |
parents | e83eef58b30a |
children |
rev | line source |
---|---|
14280 | 1 /******************************************************************** |
2 * * | |
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * | |
4 * * | |
19251
cd6b211be811
Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents:
14280
diff
changeset
|
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
cd6b211be811
Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents:
14280
diff
changeset
|
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
cd6b211be811
Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents:
14280
diff
changeset
|
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
cd6b211be811
Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents:
14280
diff
changeset
|
8 * * |
14280 | 9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * |
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * | |
11 * * | |
12 ******************************************************************** | |
13 | |
14 function: PCM data vector blocking, windowing and dis/reassembly | |
15 | |
16 ********************************************************************/ | |
17 | |
18 #include <stdio.h> | |
19 #include <stdlib.h> | |
20 #include <string.h> | |
21 #include "ogg.h" | |
22 #include "ivorbiscodec.h" | |
23 #include "codec_internal.h" | |
24 | |
25 #include "window.h" | |
26 #include "registry.h" | |
27 #include "misc.h" | |
24796
8dfda4d651ec
_vorbis_block_alloc() is used w/o prototype, this will crash on ia64.
diego
parents:
19251
diff
changeset
|
28 #include "block.h" |
14280 | 29 |
30 static int ilog(unsigned int v){ | |
31 int ret=0; | |
32 if(v)--v; | |
33 while(v){ | |
34 ret++; | |
35 v>>=1; | |
36 } | |
37 return(ret); | |
38 } | |
39 | |
40 /* pcm accumulator examples (not exhaustive): | |
41 | |
42 <-------------- lW ----------------> | |
43 <--------------- W ----------------> | |
44 : .....|..... _______________ | | |
45 : .''' | '''_--- | |\ | | |
46 :.....''' |_____--- '''......| | \_______| | |
47 :.................|__________________|_______|__|______| | |
48 |<------ Sl ------>| > Sr < |endW | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
49 |beginSl |endSl | |endSr |
14280 | 50 |beginW |endlW |beginSr |
51 | |
52 | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
53 |< lW >| |
14280 | 54 <--------------- W ----------------> |
55 | | .. ______________ | | |
56 | | ' `/ | ---_ | | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
57 |___.'___/`. | ---_____| |
14280 | 58 |_______|__|_______|_________________| |
59 | >|Sl|< |<------ Sr ----->|endW | |
60 | | |endSl |beginSr |endSr | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
61 |beginW | |endlW |
14280 | 62 mult[0] |beginSl mult[n] |
63 | |
64 <-------------- lW -----------------> | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
65 |<--W-->| |
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
66 : .............. ___ | | |
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
67 : .''' |`/ \ | | |
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
68 :.....''' |/`....\|...| |
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
69 :.........................|___|___|___| |
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
70 |Sl |Sr |endW |
14280 | 71 | | |endSr |
72 | |beginSr | |
73 | |endSl | |
74 |beginSl | |
75 |beginW | |
76 */ | |
77 | |
78 /* block abstraction setup *********************************************/ | |
79 | |
80 #ifndef WORD_ALIGN | |
81 #define WORD_ALIGN 8 | |
82 #endif | |
83 | |
84 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){ | |
85 memset(vb,0,sizeof(*vb)); | |
86 vb->vd=v; | |
87 vb->localalloc=0; | |
88 vb->localstore=NULL; | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
89 |
14280 | 90 return(0); |
91 } | |
92 | |
93 void *_vorbis_block_alloc(vorbis_block *vb,long bytes){ | |
94 bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1); | |
95 if(bytes+vb->localtop>vb->localalloc){ | |
96 /* can't just _ogg_realloc... there are outstanding pointers */ | |
97 if(vb->localstore){ | |
98 struct alloc_chain *link=(struct alloc_chain *)_ogg_malloc(sizeof(*link)); | |
99 vb->totaluse+=vb->localtop; | |
100 link->next=vb->reap; | |
101 link->ptr=vb->localstore; | |
102 vb->reap=link; | |
103 } | |
104 /* highly conservative */ | |
105 vb->localalloc=bytes; | |
106 vb->localstore=_ogg_malloc(vb->localalloc); | |
107 vb->localtop=0; | |
108 } | |
109 { | |
110 void *ret=(void *)(((char *)vb->localstore)+vb->localtop); | |
111 vb->localtop+=bytes; | |
112 return ret; | |
113 } | |
114 } | |
115 | |
116 /* reap the chain, pull the ripcord */ | |
117 void _vorbis_block_ripcord(vorbis_block *vb){ | |
118 /* reap the chain */ | |
119 struct alloc_chain *reap=vb->reap; | |
120 while(reap){ | |
121 struct alloc_chain *next=reap->next; | |
122 _ogg_free(reap->ptr); | |
123 memset(reap,0,sizeof(*reap)); | |
124 _ogg_free(reap); | |
125 reap=next; | |
126 } | |
127 /* consolidate storage */ | |
128 if(vb->totaluse){ | |
129 vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc); | |
130 vb->localalloc+=vb->totaluse; | |
131 vb->totaluse=0; | |
132 } | |
133 | |
134 /* pull the ripcord */ | |
135 vb->localtop=0; | |
136 vb->reap=NULL; | |
137 } | |
138 | |
139 int vorbis_block_clear(vorbis_block *vb){ | |
140 _vorbis_block_ripcord(vb); | |
141 if(vb->localstore)_ogg_free(vb->localstore); | |
142 | |
143 memset(vb,0,sizeof(*vb)); | |
144 return(0); | |
145 } | |
146 | |
147 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){ | |
148 int i; | |
149 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | |
150 backend_lookup_state *b=NULL; | |
151 | |
152 memset(v,0,sizeof(*v)); | |
153 b=(backend_lookup_state *)(v->backend_state=_ogg_calloc(1,sizeof(*b))); | |
154 | |
155 v->vi=vi; | |
156 b->modebits=ilog(ci->modes); | |
157 | |
158 /* Vorbis I uses only window type 0 */ | |
159 b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2); | |
160 b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2); | |
161 | |
162 /* finish the codebooks */ | |
163 if(!ci->fullbooks){ | |
164 ci->fullbooks=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); | |
165 for(i=0;i<ci->books;i++){ | |
166 vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]); | |
167 /* decode codebooks are now standalone after init */ | |
168 vorbis_staticbook_destroy(ci->book_param[i]); | |
169 ci->book_param[i]=NULL; | |
170 } | |
171 } | |
172 | |
173 v->pcm_storage=ci->blocksizes[1]; | |
174 v->pcm=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcm)); | |
175 v->pcmret=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcmret)); | |
176 for(i=0;i<vi->channels;i++) | |
177 v->pcm[i]=(ogg_int32_t *)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i])); | |
178 | |
179 /* all 1 (large block) or 0 (small block) */ | |
180 /* explicitly set for the sake of clarity */ | |
181 v->lW=0; /* previous window size */ | |
182 v->W=0; /* current window size */ | |
183 | |
184 /* all vector indexes */ | |
185 v->centerW=ci->blocksizes[1]/2; | |
186 | |
187 v->pcm_current=v->centerW; | |
188 | |
189 /* initialize all the mapping/backend lookups */ | |
190 b->mode=(vorbis_look_mapping **)_ogg_calloc(ci->modes,sizeof(*b->mode)); | |
191 for(i=0;i<ci->modes;i++){ | |
192 int mapnum=ci->mode_param[i]->mapping; | |
193 int maptype=ci->map_type[mapnum]; | |
194 b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i], | |
195 ci->map_param[mapnum]); | |
196 } | |
197 | |
198 v->pcm_returned=-1; | |
199 v->granulepos=-1; | |
200 v->sequence=-1; | |
201 | |
202 return(0); | |
203 } | |
204 | |
205 void vorbis_dsp_clear(vorbis_dsp_state *v){ | |
206 int i; | |
207 if(v){ | |
208 vorbis_info *vi=v->vi; | |
209 codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL); | |
210 backend_lookup_state *b=(backend_lookup_state *)v->backend_state; | |
211 | |
212 if(v->pcm){ | |
213 for(i=0;i<vi->channels;i++) | |
214 if(v->pcm[i])_ogg_free(v->pcm[i]); | |
215 _ogg_free(v->pcm); | |
216 if(v->pcmret)_ogg_free(v->pcmret); | |
217 } | |
218 | |
219 /* free mode lookups; these are actually vorbis_look_mapping structs */ | |
220 if(ci){ | |
221 for(i=0;i<ci->modes;i++){ | |
222 int mapnum=ci->mode_param[i]->mapping; | |
223 int maptype=ci->map_type[mapnum]; | |
224 if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]); | |
225 } | |
226 } | |
227 | |
228 if(b){ | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
229 if(b->mode)_ogg_free(b->mode); |
14280 | 230 _ogg_free(b); |
231 } | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
232 |
14280 | 233 memset(v,0,sizeof(*v)); |
234 } | |
235 } | |
236 | |
237 /* Unlike in analysis, the window is only partially applied for each | |
238 block. The time domain envelope is not yet handled at the point of | |
239 calling (as it relies on the previous block). */ | |
240 | |
241 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){ | |
242 vorbis_info *vi=v->vi; | |
243 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | |
244 int i,j; | |
245 | |
246 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL); | |
247 | |
248 v->lW=v->W; | |
249 v->W=vb->W; | |
250 v->nW=-1; | |
251 | |
252 if(v->sequence+1 != vb->sequence)v->granulepos=-1; /* out of sequence; | |
253 lose count */ | |
254 | |
255 v->sequence=vb->sequence; | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
256 |
14280 | 257 { |
258 int n=ci->blocksizes[v->W]/2; | |
259 int n0=ci->blocksizes[0]/2; | |
260 int n1=ci->blocksizes[1]/2; | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
261 |
14280 | 262 int thisCenter; |
263 int prevCenter; | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
264 |
14280 | 265 if(v->centerW){ |
266 thisCenter=n1; | |
267 prevCenter=0; | |
268 }else{ | |
269 thisCenter=0; | |
270 prevCenter=n1; | |
271 } | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
272 |
14280 | 273 /* v->pcm is now used like a two-stage double buffer. We don't want |
274 to have to constantly shift *or* adjust memory usage. Don't | |
275 accept a new block until the old is shifted out */ | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
276 |
14280 | 277 /* overlap/add PCM */ |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
278 |
14280 | 279 for(j=0;j<vi->channels;j++){ |
280 /* the overlap/add section */ | |
281 if(v->lW){ | |
282 if(v->W){ | |
283 /* large/large */ | |
284 ogg_int32_t *pcm=v->pcm[j]+prevCenter; | |
285 ogg_int32_t *p=vb->pcm[j]; | |
286 for(i=0;i<n1;i++) | |
287 pcm[i]+=p[i]; | |
288 }else{ | |
289 /* large/small */ | |
290 ogg_int32_t *pcm=v->pcm[j]+prevCenter+n1/2-n0/2; | |
291 ogg_int32_t *p=vb->pcm[j]; | |
292 for(i=0;i<n0;i++) | |
293 pcm[i]+=p[i]; | |
294 } | |
295 }else{ | |
296 if(v->W){ | |
297 /* small/large */ | |
298 ogg_int32_t *pcm=v->pcm[j]+prevCenter; | |
299 ogg_int32_t *p=vb->pcm[j]+n1/2-n0/2; | |
300 for(i=0;i<n0;i++) | |
301 pcm[i]+=p[i]; | |
302 for(;i<n1/2+n0/2;i++) | |
303 pcm[i]=p[i]; | |
304 }else{ | |
305 /* small/small */ | |
306 ogg_int32_t *pcm=v->pcm[j]+prevCenter; | |
307 ogg_int32_t *p=vb->pcm[j]; | |
308 for(i=0;i<n0;i++) | |
309 pcm[i]+=p[i]; | |
310 } | |
311 } | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
312 |
14280 | 313 /* the copy section */ |
314 { | |
315 ogg_int32_t *pcm=v->pcm[j]+thisCenter; | |
316 ogg_int32_t *p=vb->pcm[j]+n; | |
317 for(i=0;i<n;i++) | |
318 pcm[i]=p[i]; | |
319 } | |
320 } | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
321 |
14280 | 322 if(v->centerW) |
323 v->centerW=0; | |
324 else | |
325 v->centerW=n1; | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
326 |
14280 | 327 /* deal with initial packet state; we do this using the explicit |
328 pcm_returned==-1 flag otherwise we're sensitive to first block | |
329 being short or long */ | |
330 | |
331 if(v->pcm_returned==-1){ | |
332 v->pcm_returned=thisCenter; | |
333 v->pcm_current=thisCenter; | |
334 }else{ | |
335 v->pcm_returned=prevCenter; | |
336 v->pcm_current=prevCenter+ | |
337 ci->blocksizes[v->lW]/4+ | |
338 ci->blocksizes[v->W]/4; | |
339 } | |
340 | |
341 /* track the frame number... This is for convenience, but also | |
342 making sure our last packet doesn't end with added padding. If | |
343 the last packet is partial, the number of samples we'll have to | |
344 return will be past the vb->granulepos. | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
345 |
14280 | 346 This is not foolproof! It will be confused if we begin |
347 decoding at the last page after a seek or hole. In that case, | |
348 we don't have a starting point to judge where the last frame | |
349 is. For this reason, vorbisfile will always try to make sure | |
350 it reads the last two marked pages in proper sequence */ | |
351 | |
352 if(v->granulepos==-1) | |
353 if(vb->granulepos==-1){ | |
354 v->granulepos=0; | |
355 }else{ | |
356 v->granulepos=vb->granulepos; | |
357 } | |
358 else{ | |
359 v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; | |
360 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){ | |
361 | |
362 if(v->granulepos>vb->granulepos){ | |
363 long extra=v->granulepos-vb->granulepos; | |
364 | |
365 if(vb->eofflag){ | |
366 /* partial last frame. Strip the extra samples off */ | |
367 v->pcm_current-=extra; | |
368 }else if(vb->sequence == 1){ | |
369 /* ^^^ argh, this can be 1 from seeking! */ | |
370 | |
371 | |
372 /* partial first frame. Discard extra leading samples */ | |
373 v->pcm_returned+=extra; | |
374 if(v->pcm_returned>v->pcm_current) | |
375 v->pcm_returned=v->pcm_current; | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
376 |
14280 | 377 } |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
378 |
14280 | 379 }/* else{ Shouldn't happen *unless* the bitstream is out of |
380 spec. Either way, believe the bitstream } */ | |
381 v->granulepos=vb->granulepos; | |
382 } | |
383 } | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
384 |
14280 | 385 /* Update, cleanup */ |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
386 |
14280 | 387 if(vb->eofflag)v->eofflag=1; |
388 } | |
29264
e83eef58b30a
Remove all kind of trailing whitespaces from all MPlayer's files.
bircoph
parents:
24796
diff
changeset
|
389 |
14280 | 390 return(0); |
391 } | |
392 | |
393 /* pcm==NULL indicates we just want the pending samples, no more */ | |
394 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,ogg_int32_t ***pcm){ | |
395 vorbis_info *vi=v->vi; | |
396 if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){ | |
397 if(pcm){ | |
398 int i; | |
399 for(i=0;i<vi->channels;i++) | |
400 v->pcmret[i]=v->pcm[i]+v->pcm_returned; | |
401 *pcm=v->pcmret; | |
402 } | |
403 return(v->pcm_current-v->pcm_returned); | |
404 } | |
405 return(0); | |
406 } | |
407 | |
408 int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){ | |
409 if(bytes && v->pcm_returned+bytes>v->pcm_current)return(OV_EINVAL); | |
410 v->pcm_returned+=bytes; | |
411 return(0); | |
412 } | |
413 |