Mercurial > mplayer.hg
annotate tremor/res012.c @ 28018:4ac70bd6acac
MNG demuxer by Stefan Schuermans, stefan blinkenarea org
author | diego |
---|---|
date | Sun, 30 Nov 2008 13:22:34 +0000 |
parents | 8dfda4d651ec |
children | e83eef58b30a |
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: residue backend 0, 1 and 2 implementation | |
15 | |
16 ********************************************************************/ | |
17 | |
18 #include <stdlib.h> | |
19 #include <string.h> | |
20 #include <math.h> | |
21 #include "ogg.h" | |
22 #include "ivorbiscodec.h" | |
23 #include "codec_internal.h" | |
24 #include "registry.h" | |
25 #include "codebook.h" | |
26 #include "misc.h" | |
27 #include "os.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 typedef struct { | |
31 vorbis_info_residue0 *info; | |
32 int map; | |
33 | |
34 int parts; | |
35 int stages; | |
36 codebook *fullbooks; | |
37 codebook *phrasebook; | |
38 codebook ***partbooks; | |
39 | |
40 int partvals; | |
41 int **decodemap; | |
42 | |
43 } vorbis_look_residue0; | |
44 | |
45 void res0_free_info(vorbis_info_residue *i){ | |
46 vorbis_info_residue0 *info=(vorbis_info_residue0 *)i; | |
47 if(info){ | |
48 memset(info,0,sizeof(*info)); | |
49 _ogg_free(info); | |
50 } | |
51 } | |
52 | |
53 void res0_free_look(vorbis_look_residue *i){ | |
54 int j; | |
55 if(i){ | |
56 | |
57 vorbis_look_residue0 *look=(vorbis_look_residue0 *)i; | |
58 | |
59 for(j=0;j<look->parts;j++) | |
60 if(look->partbooks[j])_ogg_free(look->partbooks[j]); | |
61 _ogg_free(look->partbooks); | |
62 for(j=0;j<look->partvals;j++) | |
63 _ogg_free(look->decodemap[j]); | |
64 _ogg_free(look->decodemap); | |
65 | |
66 memset(look,0,sizeof(*look)); | |
67 _ogg_free(look); | |
68 } | |
69 } | |
70 | |
71 static int ilog(unsigned int v){ | |
72 int ret=0; | |
73 while(v){ | |
74 ret++; | |
75 v>>=1; | |
76 } | |
77 return(ret); | |
78 } | |
79 | |
80 static int icount(unsigned int v){ | |
81 int ret=0; | |
82 while(v){ | |
83 ret+=v&1; | |
84 v>>=1; | |
85 } | |
86 return(ret); | |
87 } | |
88 | |
89 /* vorbis_info is for range checking */ | |
90 vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){ | |
91 int j,acc=0; | |
92 vorbis_info_residue0 *info=(vorbis_info_residue0 *)_ogg_calloc(1,sizeof(*info)); | |
93 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | |
94 | |
95 info->begin=oggpack_read(opb,24); | |
96 info->end=oggpack_read(opb,24); | |
97 info->grouping=oggpack_read(opb,24)+1; | |
98 info->partitions=oggpack_read(opb,6)+1; | |
99 info->groupbook=oggpack_read(opb,8); | |
100 | |
101 for(j=0;j<info->partitions;j++){ | |
102 int cascade=oggpack_read(opb,3); | |
103 if(oggpack_read(opb,1)) | |
104 cascade|=(oggpack_read(opb,5)<<3); | |
105 info->secondstages[j]=cascade; | |
106 | |
107 acc+=icount(cascade); | |
108 } | |
109 for(j=0;j<acc;j++) | |
110 info->booklist[j]=oggpack_read(opb,8); | |
111 | |
112 if(info->groupbook>=ci->books)goto errout; | |
113 for(j=0;j<acc;j++) | |
114 if(info->booklist[j]>=ci->books)goto errout; | |
115 | |
116 return(info); | |
117 errout: | |
118 res0_free_info(info); | |
119 return(NULL); | |
120 } | |
121 | |
122 vorbis_look_residue *res0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm, | |
123 vorbis_info_residue *vr){ | |
124 vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; | |
125 vorbis_look_residue0 *look=(vorbis_look_residue0 *)_ogg_calloc(1,sizeof(*look)); | |
126 codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; | |
127 | |
128 int j,k,acc=0; | |
129 int dim; | |
130 int maxstage=0; | |
131 look->info=info; | |
132 look->map=vm->mapping; | |
133 | |
134 look->parts=info->partitions; | |
135 look->fullbooks=ci->fullbooks; | |
136 look->phrasebook=ci->fullbooks+info->groupbook; | |
137 dim=look->phrasebook->dim; | |
138 | |
139 look->partbooks=(codebook ***)_ogg_calloc(look->parts,sizeof(*look->partbooks)); | |
140 | |
141 for(j=0;j<look->parts;j++){ | |
142 int stages=ilog(info->secondstages[j]); | |
143 if(stages){ | |
144 if(stages>maxstage)maxstage=stages; | |
145 look->partbooks[j]=(codebook **)_ogg_calloc(stages,sizeof(*look->partbooks[j])); | |
146 for(k=0;k<stages;k++) | |
147 if(info->secondstages[j]&(1<<k)){ | |
148 look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++]; | |
149 #ifdef TRAIN_RES | |
150 look->training_data[k][j]=calloc(look->partbooks[j][k]->entries, | |
151 sizeof(***look->training_data)); | |
152 #endif | |
153 } | |
154 } | |
155 } | |
156 | |
157 look->partvals=look->parts; | |
158 for(j=1;j<dim;j++)look->partvals*=look->parts; | |
159 look->stages=maxstage; | |
160 look->decodemap=(int **)_ogg_malloc(look->partvals*sizeof(*look->decodemap)); | |
161 for(j=0;j<look->partvals;j++){ | |
162 long val=j; | |
163 long mult=look->partvals/look->parts; | |
164 look->decodemap[j]=(int *)_ogg_malloc(dim*sizeof(*look->decodemap[j])); | |
165 for(k=0;k<dim;k++){ | |
166 long deco=val/mult; | |
167 val-=deco*mult; | |
168 mult/=look->parts; | |
169 look->decodemap[j][k]=deco; | |
170 } | |
171 } | |
172 | |
173 return(look); | |
174 } | |
175 | |
176 | |
177 /* a truncated packet here just means 'stop working'; it's not an error */ | |
178 static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl, | |
179 ogg_int32_t **in,int ch, | |
180 long (*decodepart)(codebook *, ogg_int32_t *, | |
181 oggpack_buffer *,int,int)){ | |
182 | |
183 long i,j,k,l,s; | |
184 vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; | |
185 vorbis_info_residue0 *info=look->info; | |
186 | |
187 /* move all this setup out later */ | |
188 int samples_per_partition=info->grouping; | |
189 int partitions_per_word=look->phrasebook->dim; | |
190 int n=info->end-info->begin; | |
191 | |
192 int partvals=n/samples_per_partition; | |
193 int partwords=(partvals+partitions_per_word-1)/partitions_per_word; | |
194 int ***partword=(int ***)alloca(ch*sizeof(*partword)); | |
195 | |
196 for(j=0;j<ch;j++) | |
197 partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j])); | |
198 | |
199 for(s=0;s<look->stages;s++){ | |
200 | |
201 /* each loop decodes on partition codeword containing | |
202 partitions_pre_word partitions */ | |
203 for(i=0,l=0;i<partvals;l++){ | |
204 if(s==0){ | |
205 /* fetch the partition word for each channel */ | |
206 for(j=0;j<ch;j++){ | |
207 int temp=vorbis_book_decode(look->phrasebook,&vb->opb); | |
208 if(temp==-1)goto eopbreak; | |
209 partword[j][l]=look->decodemap[temp]; | |
210 if(partword[j][l]==NULL)goto errout; | |
211 } | |
212 } | |
213 | |
214 /* now we decode residual values for the partitions */ | |
215 for(k=0;k<partitions_per_word && i<partvals;k++,i++) | |
216 for(j=0;j<ch;j++){ | |
217 long offset=info->begin+i*samples_per_partition; | |
218 if(info->secondstages[partword[j][l][k]]&(1<<s)){ | |
219 codebook *stagebook=look->partbooks[partword[j][l][k]][s]; | |
220 if(stagebook){ | |
221 if(decodepart(stagebook,in[j]+offset,&vb->opb, | |
222 samples_per_partition,-8)==-1)goto eopbreak; | |
223 } | |
224 } | |
225 } | |
226 } | |
227 } | |
228 | |
229 errout: | |
230 eopbreak: | |
231 return(0); | |
232 } | |
233 | |
234 int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl, | |
235 ogg_int32_t **in,int *nonzero,int ch){ | |
236 int i,used=0; | |
237 for(i=0;i<ch;i++) | |
238 if(nonzero[i]) | |
239 in[used++]=in[i]; | |
240 if(used) | |
241 return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add)); | |
242 else | |
243 return(0); | |
244 } | |
245 | |
246 int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl, | |
247 ogg_int32_t **in,int *nonzero,int ch){ | |
248 int i,used=0; | |
249 for(i=0;i<ch;i++) | |
250 if(nonzero[i]) | |
251 in[used++]=in[i]; | |
252 if(used) | |
253 return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add)); | |
254 else | |
255 return(0); | |
256 } | |
257 | |
258 /* duplicate code here as speed is somewhat more important */ | |
259 int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl, | |
260 ogg_int32_t **in,int *nonzero,int ch){ | |
261 long i,k,l,s; | |
262 vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; | |
263 vorbis_info_residue0 *info=look->info; | |
264 | |
265 /* move all this setup out later */ | |
266 int samples_per_partition=info->grouping; | |
267 int partitions_per_word=look->phrasebook->dim; | |
268 int n=info->end-info->begin; | |
269 | |
270 int partvals=n/samples_per_partition; | |
271 int partwords=(partvals+partitions_per_word-1)/partitions_per_word; | |
272 int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword)); | |
273 int beginoff=info->begin/ch; | |
274 | |
275 for(i=0;i<ch;i++)if(nonzero[i])break; | |
276 if(i==ch)return(0); /* no nonzero vectors */ | |
277 | |
278 samples_per_partition/=ch; | |
279 | |
280 for(s=0;s<look->stages;s++){ | |
281 for(i=0,l=0;i<partvals;l++){ | |
282 | |
283 if(s==0){ | |
284 /* fetch the partition word */ | |
285 int temp=vorbis_book_decode(look->phrasebook,&vb->opb); | |
286 if(temp==-1)goto eopbreak; | |
287 partword[l]=look->decodemap[temp]; | |
288 if(partword[l]==NULL)goto errout; | |
289 } | |
290 | |
291 /* now we decode residual values for the partitions */ | |
292 for(k=0;k<partitions_per_word && i<partvals;k++,i++) | |
293 if(info->secondstages[partword[l][k]]&(1<<s)){ | |
294 codebook *stagebook=look->partbooks[partword[l][k]][s]; | |
295 | |
296 if(stagebook){ | |
297 if(vorbis_book_decodevv_add(stagebook,in, | |
298 i*samples_per_partition+beginoff,ch, | |
299 &vb->opb, | |
300 samples_per_partition,-8)==-1) | |
301 goto eopbreak; | |
302 } | |
303 } | |
304 } | |
305 } | |
306 | |
307 errout: | |
308 eopbreak: | |
309 return(0); | |
310 } | |
311 | |
312 | |
313 vorbis_func_residue residue0_exportbundle={ | |
314 &res0_unpack, | |
315 &res0_look, | |
316 &res0_free_info, | |
317 &res0_free_look, | |
318 &res0_inverse | |
319 }; | |
320 | |
321 vorbis_func_residue residue1_exportbundle={ | |
322 &res0_unpack, | |
323 &res0_look, | |
324 &res0_free_info, | |
325 &res0_free_look, | |
326 &res1_inverse | |
327 }; | |
328 | |
329 vorbis_func_residue residue2_exportbundle={ | |
330 &res0_unpack, | |
331 &res0_look, | |
332 &res0_free_info, | |
333 &res0_free_look, | |
334 &res2_inverse | |
335 }; |