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