Mercurial > mplayer.hg
annotate libmpcodecs/ad_twin.c @ 34953:359ceed74184
Fix crash for -vo sdl -fs when running under X.
author | reimar |
---|---|
date | Mon, 23 Jul 2012 18:59:20 +0000 |
parents | a93891202051 |
children |
rev | line source |
---|---|
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
1 /* |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
2 * This file is part of MPlayer. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
3 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
4 * MPlayer is free software; you can redistribute it and/or modify |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
7 * (at your option) any later version. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
8 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
9 * MPlayer is distributed in the hope that it will be useful, |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
12 * GNU General Public License for more details. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
13 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
14 * You should have received a copy of the GNU General Public License along |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
17 */ |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29702
diff
changeset
|
18 |
14276 | 19 #include <stdio.h> |
20 #include <stdlib.h> | |
21 #include <unistd.h> | |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
30589
diff
changeset
|
22 |
14276 | 23 #include "config.h" |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
30589
diff
changeset
|
24 #include "mp_msg.h" |
14276 | 25 #include "ad_internal.h" |
26 #include "vqf.h" | |
30589
df6c41f16b40
Add header for AVI print functions; avoids many forward declarations.
diego
parents:
30504
diff
changeset
|
27 #include "libmpdemux/aviprint.h" |
17012 | 28 #include "loader/ldt_keeper.h" |
22577
a033e5519802
Include loader/ prefix in #include path everywhere.
diego
parents:
18771
diff
changeset
|
29 #include "loader/wine/windef.h" |
17012 | 30 #include "libaf/af_format.h" |
14276 | 31 |
32 #include "help_mp.h" | |
33 | |
30504
cc27da5d7286
Mark all ad_info_t/vd_info_t structure declarations as const.
diego
parents:
30421
diff
changeset
|
34 static const ad_info_t info = |
14276 | 35 { |
36 "TWinVQ decoder", | |
37 "vqf", | |
38 "Roberto Togni", | |
39 "Nick Kurshev", | |
40 "Ported from MPlayerXP" | |
41 }; | |
42 | |
43 LIBAD_EXTERN(twin) | |
44 | |
45 void* WINAPI LoadLibraryA(char* name); | |
46 void* WINAPI GetProcAddress(void* handle, char* func); | |
47 int WINAPI FreeLibrary(void* handle); | |
48 | |
49 static int (*TvqInitialize)( headerInfo *setupInfo, INDEX *index, int dispErrorMessageBox ); | |
50 static void (*TvqTerminate)( INDEX *index ); | |
51 static void (*TvqGetVectorInfo)(int *bits0[], int *bits1[]); | |
52 | |
53 static void (*TvqDecodeFrame)(INDEX *indexp, float out[]); | |
54 static int (*TvqWtypeToBtype)( int w_type, int *btype ); | |
55 static void (*TvqUpdateVectorInfo)(int varbits, int *ndiv, int bits0[], int bits1[]); | |
56 | |
57 static int (*TvqCheckVersion)(char *versionID); | |
58 static void (*TvqGetConfInfo)(tvqConfInfo *cf); | |
59 static int (*TvqGetFrameSize)(); | |
60 static int (*TvqGetNumFixedBitsPerFrame)(); | |
61 | |
62 #define BYTE_BIT 8 | |
63 #define BBUFSIZ 1024 /* Bit buffer size (bytes) */ | |
64 #define BBUFLEN (BBUFSIZ*BYTE_BIT) /* Bit buffer length (bits) */ | |
65 typedef struct vqf_priv_s | |
66 { | |
67 float pts; | |
68 WAVEFORMATEX o_wf; // out format | |
69 INDEX index; | |
70 tvqConfInfo cf; | |
71 headerInfo hi; | |
72 int *bits_0[N_INTR_TYPE], *bits_1[N_INTR_TYPE]; | |
73 unsigned framesize; | |
74 /* stream related */ | |
75 int readable; | |
76 int ptr; /* current point in the bit buffer */ | |
77 int nbuf; /* bit buffer size */ | |
78 char buf[BBUFSIZ]; /* the bit buffer */ | |
79 int skip_cnt; | |
80 }vqf_priv_t; | |
81 | |
82 static void* vqf_dll; | |
83 | |
84 static int load_dll( char *libname ) | |
85 { | |
86 #ifdef WIN32_LOADER | |
87 Setup_LDT_Keeper(); | |
88 #endif | |
89 vqf_dll = LoadLibraryA(libname); | |
90 if( vqf_dll == NULL ) | |
91 { | |
92 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "failed loading dll\n" ); | |
93 return 0; | |
94 } | |
95 TvqInitialize = GetProcAddress(vqf_dll,"TvqInitialize"); | |
96 TvqTerminate = GetProcAddress(vqf_dll,"TvqTerminate"); | |
97 TvqGetVectorInfo = GetProcAddress(vqf_dll,"TvqGetVectorInfo"); | |
98 TvqDecodeFrame = GetProcAddress(vqf_dll,"TvqDecodeFrame"); | |
99 TvqWtypeToBtype = GetProcAddress(vqf_dll,"TvqWtypeToBtype"); | |
100 TvqUpdateVectorInfo = GetProcAddress(vqf_dll,"TvqUpdateVectorInfo"); | |
101 TvqCheckVersion = GetProcAddress(vqf_dll,"TvqCheckVersion"); | |
102 TvqGetConfInfo = GetProcAddress(vqf_dll,"TvqGetConfInfo"); | |
103 TvqGetFrameSize = GetProcAddress(vqf_dll,"TvqGetFrameSize"); | |
104 TvqGetNumFixedBitsPerFrame = GetProcAddress(vqf_dll,"TvqGetNumFixedBitsPerFrame"); | |
105 return TvqInitialize && TvqTerminate && TvqGetVectorInfo && | |
106 TvqDecodeFrame && TvqWtypeToBtype && TvqUpdateVectorInfo && | |
107 TvqCheckVersion && TvqGetConfInfo && TvqGetFrameSize && | |
108 TvqGetNumFixedBitsPerFrame; | |
109 } | |
110 | |
111 static int init_vqf_audio_codec(sh_audio_t *sh_audio){ | |
112 WAVEFORMATEX *in_fmt=sh_audio->wf; | |
113 vqf_priv_t*priv=sh_audio->context; | |
114 int ver; | |
115 mp_msg(MSGT_DECAUDIO, MSGL_INFO, "======= Win32 (TWinVQ) AUDIO Codec init =======\n"); | |
116 | |
117 sh_audio->channels=in_fmt->nChannels; | |
118 sh_audio->samplerate=in_fmt->nSamplesPerSec; | |
119 sh_audio->sample_format=AF_FORMAT_S16_NE; | |
120 // sh_audio->sample_format=AF_FORMAT_FLOAT_NE; | |
121 sh_audio->samplesize=af_fmt2bits(sh_audio->sample_format)/8; | |
122 priv->o_wf.nChannels=in_fmt->nChannels; | |
123 priv->o_wf.nSamplesPerSec=in_fmt->nSamplesPerSec; | |
124 priv->o_wf.nBlockAlign=sh_audio->samplesize*in_fmt->nChannels; | |
125 priv->o_wf.nAvgBytesPerSec=in_fmt->nBlockAlign*in_fmt->nChannels; | |
126 priv->o_wf.wFormatTag=0x01; | |
127 priv->o_wf.wBitsPerSample=in_fmt->wBitsPerSample; | |
128 priv->o_wf.cbSize=0; | |
129 | |
17932 | 130 if( mp_msg_test(MSGT_DECAUDIO,MSGL_V) ) |
14276 | 131 { |
17932 | 132 mp_msg(MSGT_DECAUDIO, MSGL_V, "Input format:\n"); |
17977
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
17932
diff
changeset
|
133 print_wave_header(in_fmt, MSGL_V); |
17932 | 134 mp_msg(MSGT_DECAUDIO, MSGL_V, "Output fmt:\n"); |
17977
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
17932
diff
changeset
|
135 print_wave_header(&priv->o_wf, MSGL_V); |
14276 | 136 } |
137 memcpy(&priv->hi,&in_fmt[1],sizeof(headerInfo)); | |
138 if((ver=TvqInitialize(&priv->hi,&priv->index,0))){ | |
139 const char *tvqe[]={ | |
140 "No errors", | |
141 "General error", | |
142 "Wrong version", | |
143 "Channel setting error", | |
144 "Wrong coding mode", | |
145 "Inner parameter setting error", | |
146 "Wrong number of VQ pre-selection candidates, used only in encoder" }; | |
147 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq initialization error: %s\n",ver>=0&&ver<7?tvqe[ver]:"Unknown"); | |
148 return 0; | |
149 } | |
150 ver=TvqCheckVersion(priv->hi.ID); | |
151 if(ver==TVQ_UNKNOWN_VERSION){ | |
152 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq unknown version of stream\n" ); | |
153 return 0; | |
154 } | |
155 TvqGetConfInfo(&priv->cf); | |
156 TvqGetVectorInfo(priv->bits_0,priv->bits_1); | |
157 priv->framesize=TvqGetFrameSize(); | |
158 sh_audio->audio_in_minsize=priv->framesize*in_fmt->nChannels; | |
159 sh_audio->a_in_buffer_size=4*sh_audio->audio_in_minsize; | |
27765
03bb6c3945ff
Use av_malloc/av_free for audio-related buffers to avoid crashes due to
reimar
parents:
26754
diff
changeset
|
160 sh_audio->a_in_buffer=av_malloc(sh_audio->a_in_buffer_size); |
14276 | 161 sh_audio->a_in_buffer_len=0; |
162 | |
163 | |
164 return 1; | |
165 } | |
166 | |
167 static int close_vqf_audio_codec(sh_audio_t *sh_audio) | |
168 { | |
169 vqf_priv_t*priv=sh_audio->context; | |
170 TvqTerminate(&priv->index); | |
171 return 1; | |
172 } | |
173 | |
174 int init(sh_audio_t *sh_audio) | |
175 { | |
176 return 1; | |
177 } | |
178 | |
179 int preinit(sh_audio_t *sh_audio) | |
180 { | |
181 /* Win32 VQF audio codec: */ | |
182 vqf_priv_t *priv; | |
183 if(!(sh_audio->context=malloc(sizeof(vqf_priv_t)))) return 0; | |
184 priv=sh_audio->context; | |
185 if(!load_dll(sh_audio->codec->dll)) | |
186 { | |
187 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "win32.dll looks broken :(\n"); | |
188 return 0; | |
189 } | |
190 if(!init_vqf_audio_codec(sh_audio)){ | |
191 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "TWinVQ initialization fail\n"); | |
192 return 0; | |
193 } | |
194 mp_msg(MSGT_DECAUDIO, MSGL_INFO, "INFO: TWinVQ (%s) audio codec init OK!\n",sh_audio->codec->dll); | |
195 priv->skip_cnt = 2; | |
196 return 1; | |
197 } | |
198 | |
199 void uninit(sh_audio_t *sh) | |
200 { | |
201 close_vqf_audio_codec(sh); | |
202 free(sh->context); | |
203 FreeLibrary(vqf_dll); | |
204 } | |
205 | |
29702
28fb967d78d8
Mark some functions that do not need external visibility as static.
diego
parents:
29263
diff
changeset
|
206 static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...) |
14276 | 207 { |
208 switch(cmd) { | |
209 case ADCTRL_QUERY_FORMAT: | |
210 return CONTROL_TRUE; | |
211 default: | |
212 return CONTROL_UNKNOWN; | |
213 } | |
214 } | |
215 | |
216 static int bread(char *data, /* Output: Output data array */ | |
217 int size, /* Input: Length of each data */ | |
218 int nbits, /* Input: Number of bits to write */ | |
219 sh_audio_t *sh) /* Input: File pointer */ | |
220 { | |
221 /*--- Variables ---*/ | |
222 int ibits, iptr, idata, ibufadr, ibufbit, icl; | |
223 unsigned char mask, tmpdat; | |
224 int retval; | |
225 vqf_priv_t *priv=sh->context; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
226 |
14276 | 227 /*--- Main operation ---*/ |
228 retval = 0; | |
229 mask = 0x1; | |
230 for ( ibits=0; ibits<nbits; ibits++ ){ | |
231 if ( priv->readable == 0 ){ /* when the file data buffer is empty */ | |
232 priv->nbuf = demux_read_data(sh->ds, priv->buf, BBUFSIZ); | |
233 priv->nbuf *= 8; | |
234 priv->readable = 1; | |
235 } | |
236 iptr = priv->ptr; /* current file data buffer pointer */ | |
237 if ( iptr >= priv->nbuf ) /* If data file is empty then return */ | |
26754
63630c09e237
cosmetics: Remove pointless parentheses from return calls.
diego
parents:
22577
diff
changeset
|
238 return retval; |
14276 | 239 ibufadr = iptr/BYTE_BIT; /* current file data buffer address */ |
240 ibufbit = iptr%BYTE_BIT; /* current file data buffer bit */ | |
241 /* tmpdat = stream->buf[ibufadr] >> (BYTE_BIT-ibufbit-1); */ | |
242 tmpdat = (unsigned char)priv->buf[ibufadr]; | |
243 tmpdat >>= (BYTE_BIT-ibufbit-1); | |
244 /* current data bit */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
245 |
14276 | 246 idata = ibits*size; /* output data address */ |
247 data[idata] = (char)(tmpdat & mask); /* set output data */ | |
248 for (icl=1; icl<size; icl++) | |
249 data[idata+icl] = 0; /* clear the rest output data buffer */ | |
250 priv->ptr += 1; /* update data buffer pointer */ | |
251 if (priv->ptr == BBUFLEN){ | |
252 priv->ptr = 0; | |
253 priv->readable = 0; | |
254 } | |
255 ++retval; | |
256 } | |
26754
63630c09e237
cosmetics: Remove pointless parentheses from return calls.
diego
parents:
22577
diff
changeset
|
257 return retval; |
14276 | 258 } |
259 | |
260 #define BITS_INT (sizeof(int)*8) | |
261 | |
262 static int get_bstm(int *data, /* Input: input data */ | |
263 unsigned nbits, /* Input: number of bits */ | |
264 sh_audio_t *sh) /* Input: bit file pointer */ | |
265 { | |
266 unsigned ibit; | |
267 unsigned mask; | |
268 unsigned work; | |
269 char tmpbit[BITS_INT]; | |
270 int retval; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
271 |
14276 | 272 if ( nbits > BITS_INT ){ |
273 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "get_bstm(): %d: %d Error.\n", | |
274 nbits, BITS_INT); | |
275 exit(1); | |
276 } | |
277 retval = bread(tmpbit, sizeof(*tmpbit), nbits, sh); | |
278 for (ibit=retval; ibit<nbits; ibit++){ | |
279 tmpbit[ibit] = 0; | |
280 } | |
281 mask = 0x1<<(nbits-1); | |
282 work=0; | |
283 for ( ibit=0; ibit<nbits; ibit++ ){ | |
284 work += mask*tmpbit[ibit]; | |
285 mask >>= 1; | |
286 } | |
287 *data = work; | |
26754
63630c09e237
cosmetics: Remove pointless parentheses from return calls.
diego
parents:
22577
diff
changeset
|
288 return retval; |
14276 | 289 } |
290 | |
291 static int GetVqInfo( tvqConfInfoSubBlock *cfg, | |
292 int bits0[], | |
293 int bits1[], | |
294 int variableBits, | |
295 INDEX *index, | |
296 sh_audio_t *sh) | |
297 { | |
298 int idiv; | |
299 int bitcount = 0; | |
300 | |
301 if ( index->btype == BLK_LONG ){ | |
302 TvqUpdateVectorInfo( variableBits, &cfg->ndiv, bits0, bits1 ); // re-calculate VQ bits | |
303 } | |
304 for ( idiv=0; idiv<cfg->ndiv; idiv++ ){ | |
305 bitcount += get_bstm(&index->wvq[idiv],bits0[idiv],sh); /* CB 0 */ | |
306 bitcount += get_bstm(&index->wvq[idiv+cfg->ndiv],bits1[idiv],sh); /* CB 1 */ | |
307 } | |
308 return bitcount; | |
309 } | |
310 | |
311 static int GetBseInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh) | |
312 { | |
313 int i_sup, isf, itmp, idiv; | |
314 int bitcount = 0; | |
315 | |
316 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ | |
317 for ( isf=0; isf<cfg->nsf; isf++ ){ | |
318 for ( idiv=0; idiv<cfg->fw_ndiv; idiv++ ){ | |
319 itmp = idiv + ( isf + i_sup * cfg->nsf ) * cfg->fw_ndiv; | |
320 bitcount += get_bstm(&index->fw[itmp],cfg->fw_nbit,sh); | |
321 } | |
322 } | |
323 } | |
324 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ | |
325 for ( isf=0; isf<cfg->nsf; isf++ ){ | |
326 bitcount += get_bstm(&index->fw_alf[i_sup * cfg->nsf + isf],cf->FW_ARSW_BITS,sh); | |
327 } | |
328 } | |
329 return bitcount; | |
330 } | |
331 | |
332 static int GetGainInfo(tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh ) | |
333 { | |
334 int i_sup, iptop, isf; | |
335 int bitcount = 0; | |
336 | |
337 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ | |
338 iptop = ( cfg->nsubg + 1 ) * i_sup; | |
339 bitcount += get_bstm(&index->pow[iptop], cf->GAIN_BITS,sh); | |
340 for ( isf=0; isf<cfg->nsubg; isf++ ){ | |
341 bitcount += get_bstm(&index->pow[iptop+isf+1], cf->SUB_GAIN_BITS,sh); | |
342 } | |
343 } | |
344 return bitcount; | |
345 } | |
346 | |
347 static int GetLspInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh ) | |
348 { | |
349 int i_sup, itmp; | |
350 int bitcount = 0; | |
351 | |
352 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ | |
353 bitcount += get_bstm(&index->lsp[i_sup][0], cf->LSP_BIT0,sh); /* pred. switch */ | |
354 bitcount += get_bstm(&index->lsp[i_sup][1], cf->LSP_BIT1,sh); /* first stage */ | |
355 for ( itmp=0; itmp<cf->LSP_SPLIT; itmp++ ){ /* second stage */ | |
356 bitcount += get_bstm(&index->lsp[i_sup][itmp+2], cf->LSP_BIT2,sh); | |
357 } | |
358 } | |
359 | |
360 return bitcount; | |
361 } | |
362 | |
363 static int GetPpcInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh) | |
364 { | |
365 int idiv, i_sup; | |
366 int bitcount = 0; | |
367 vqf_priv_t*priv=sh->context; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
368 |
14276 | 369 for ( idiv=0; idiv<cf->N_DIV_P; idiv++ ){ |
370 bitcount += get_bstm(&(index->pls[idiv]), priv->bits_0[BLK_PPC][idiv],sh); /*CB0*/ | |
371 bitcount += get_bstm(&(index->pls[idiv+cf->N_DIV_P]), priv->bits_1[BLK_PPC][idiv],sh);/*CB1*/ | |
372 } | |
373 for (i_sup=0; i_sup<cf->N_CH; i_sup++){ | |
374 bitcount += get_bstm(&(index->pit[i_sup]), cf->BASF_BIT,sh); | |
375 bitcount += get_bstm(&(index->pgain[i_sup]), cf->PGAIN_BIT,sh); | |
376 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
377 |
14276 | 378 return bitcount; |
379 } | |
380 | |
381 static int GetEbcInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh) | |
382 { | |
383 int i_sup, isf, itmp; | |
384 int bitcount = 0; | |
385 | |
386 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ | |
387 for ( isf=0; isf<cfg->nsf; isf++){ | |
388 int indexSfOffset = isf * ( cfg->ncrb - cfg->ebc_crb_base ) - cfg->ebc_crb_base; | |
389 for ( itmp=cfg->ebc_crb_base; itmp<cfg->ncrb; itmp++ ){ | |
390 bitcount += get_bstm(&index->bc[i_sup][itmp+indexSfOffset], cfg->ebc_bits,sh); | |
391 } | |
392 } | |
393 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
394 |
14276 | 395 return bitcount; |
396 } | |
397 | |
398 static int vqf_read_frame(sh_audio_t *sh,INDEX *index) | |
399 { | |
400 /*--- Variables ---*/ | |
401 tvqConfInfoSubBlock *cfg; | |
402 int variableBits; | |
403 int bitcount; | |
404 int numFixedBitsPerFrame = TvqGetNumFixedBitsPerFrame(); | |
405 int btype; | |
406 vqf_priv_t *priv=sh->context; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
407 |
14276 | 408 /*--- Initialization ---*/ |
409 variableBits = 0; | |
410 bitcount = 0; | |
411 | |
412 /*--- read block independent factors ---*/ | |
413 /* Window type */ | |
414 bitcount += get_bstm( &index->w_type, priv->cf.BITS_WTYPE, sh ); | |
415 if ( TvqWtypeToBtype( index->w_type, &index->btype ) ) { | |
416 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error: unknown window type: %d\n", index->w_type); | |
417 return 0; | |
418 } | |
419 btype = index->btype; | |
420 | |
421 /*--- read block dependent factors ---*/ | |
422 cfg = &priv->cf.cfg[btype]; // set the block dependent paremeters table | |
423 | |
424 bitcount += variableBits; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
425 |
14276 | 426 /* Interleaved vector quantization */ |
427 bitcount += GetVqInfo( cfg, priv->bits_0[btype], priv->bits_1[btype], variableBits, index, sh ); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
428 |
14276 | 429 /* Bark-scale envelope */ |
430 bitcount += GetBseInfo( &priv->cf, cfg, index, sh ); | |
431 /* Gain */ | |
432 bitcount += GetGainInfo( &priv->cf, cfg, index, sh ); | |
433 /* LSP */ | |
434 bitcount += GetLspInfo( &priv->cf, index, sh ); | |
435 /* PPC */ | |
436 if ( cfg->ppc_enable ){ | |
437 bitcount += GetPpcInfo( &priv->cf, index, sh ); | |
438 } | |
439 /* Energy Balance Calibration */ | |
440 if ( cfg->ebc_enable ){ | |
441 bitcount += GetEbcInfo( &priv->cf, cfg, index, sh ); | |
442 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
443 |
14276 | 444 return bitcount == numFixedBitsPerFrame ? bitcount/8 : 0; |
445 } | |
446 | |
447 static void frtobuf_s16(float out[], /* Input --- input data frame */ | |
448 short bufout[], /* Output --- output data buffer array */ | |
449 unsigned frameSize, /* Input --- frame size */ | |
450 unsigned numChannels) /* Input --- number of channels */ | |
451 { | |
452 /*--- Variables ---*/ | |
453 unsigned ismp, ich; | |
454 float *ptr; | |
455 float dtmp; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
456 |
14276 | 457 for ( ich=0; ich<numChannels; ich++ ){ |
458 ptr = out+ich*frameSize; | |
459 for ( ismp=0; ismp<frameSize; ismp++ ){ | |
460 dtmp = ptr[ismp]; | |
461 if ( dtmp >= 0. ) { | |
462 if ( dtmp > 32700. ) | |
463 dtmp = 32700.; | |
464 bufout[ismp*numChannels+ich] = (short)(dtmp+0.5); | |
465 } else { | |
466 if ( dtmp < -32700. ) | |
467 dtmp = -32700.; | |
468 bufout[ismp*numChannels+ich] = (short)(dtmp-0.5); | |
469 } | |
470 } | |
471 } | |
472 } | |
473 | |
474 static void frtobuf_float(float out[], /* Input --- input data frame */ | |
475 float bufout[], /* Output --- output data buffer array */ | |
476 unsigned frameSize, /* Input --- frame size */ | |
477 unsigned numChannels) /* Input --- number of channels */ | |
478 { | |
479 /*--- Variables ---*/ | |
480 unsigned ismp, ich; | |
481 float *ptr; | |
482 float dtmp; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28051
diff
changeset
|
483 |
14276 | 484 for ( ich=0; ich<numChannels; ich++ ){ |
485 ptr = out+ich*frameSize; | |
486 for ( ismp=0; ismp<frameSize; ismp++ ){ | |
487 dtmp = ptr[ismp]; | |
488 if ( dtmp >= 0. ) { | |
489 if ( dtmp > 32700. ) | |
490 dtmp = 32700.; | |
491 bufout[ismp*numChannels+ich] = dtmp/32767.; | |
492 } else { | |
493 if ( dtmp < -32700. ) | |
494 dtmp = -32700.; | |
495 bufout[ismp*numChannels+ich] = dtmp/32767.; | |
496 } | |
497 } | |
498 } | |
499 } | |
500 | |
501 int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) | |
502 { | |
503 int l, len=0; | |
504 vqf_priv_t *priv=sh_audio->context; | |
505 while(len<minlen) | |
506 { | |
507 float out[priv->framesize*sh_audio->channels]; | |
508 l=vqf_read_frame(sh_audio,&priv->index); | |
509 if(!l) break; | |
510 TvqDecodeFrame(&priv->index, out); | |
511 if (priv->skip_cnt) { | |
512 // Ingnore first two frames, replace them with silence | |
513 priv->skip_cnt--; | |
514 memset(buf, 0, priv->framesize*sh_audio->channels*sh_audio->samplesize); | |
515 } else { | |
516 if (sh_audio->sample_format == AF_FORMAT_S16_NE) | |
517 frtobuf_s16(out, (short *)buf, priv->framesize, sh_audio->channels); | |
518 else | |
519 frtobuf_float(out, (float *)buf, priv->framesize, sh_audio->channels); | |
520 } | |
521 len += priv->framesize*sh_audio->channels*sh_audio->samplesize; | |
522 buf += priv->framesize*sh_audio->channels*sh_audio->samplesize; | |
523 } | |
524 return len; | |
525 } |