1 /*
2 * This file is part of MPlayer.
3 *
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22
23 #include "config.h"
24 #include "mp_msg.h"
25 #include "ad_internal.h"
26 #include "vqf.h"
27 #include "libmpdemux/aviprint.h"
28 #include "loader/ldt_keeper.h"
29 #include "loader/wine/windef.h"
30 #include "libaf/af_format.h"
31
32 #include "help_mp.h"
33
34 static const ad_info_t info =
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
load_dll(char * libname)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
init_vqf_audio_codec(sh_audio_t * sh_audio)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
130 if( mp_msg_test(MSGT_DECAUDIO,MSGL_V) )
131 {
132 mp_msg(MSGT_DECAUDIO, MSGL_V, "Input format:\n");
133 print_wave_header(in_fmt, MSGL_V);
134 mp_msg(MSGT_DECAUDIO, MSGL_V, "Output fmt:\n");
135 print_wave_header(&priv->o_wf, MSGL_V);
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;
160 sh_audio->a_in_buffer=av_malloc(sh_audio->a_in_buffer_size);
161 sh_audio->a_in_buffer_len=0;
162
163
164 return 1;
165 }
166
close_vqf_audio_codec(sh_audio_t * sh_audio)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
init(sh_audio_t * sh_audio)174 int init(sh_audio_t *sh_audio)
175 {
176 return 1;
177 }
178
preinit(sh_audio_t * sh_audio)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(codec_idx2str(sh_audio->codec->dll_idx)))
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",codec_idx2str(sh_audio->codec->dll_idx));
195 priv->skip_cnt = 2;
196 return 1;
197 }
198
uninit(sh_audio_t * sh)199 void uninit(sh_audio_t *sh)
200 {
201 close_vqf_audio_codec(sh);
202 free(sh->context);
203 FreeLibrary(vqf_dll);
204 }
205
control(sh_audio_t * sh_audio,int cmd,void * arg,...)206 static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...)
207 {
208 switch(cmd) {
209 case ADCTRL_QUERY_FORMAT:
210 return CONTROL_TRUE;
211 default:
212 return CONTROL_UNKNOWN;
213 }
214 }
215
bread(char * data,int size,int nbits,sh_audio_t * sh)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;
226
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 */
238 return retval;
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 */
245
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 }
257 return retval;
258 }
259
260 #define BITS_INT (sizeof(int)*8)
261
get_bstm(int * data,unsigned nbits,sh_audio_t * sh)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;
271
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;
288 return retval;
289 }
290
GetVqInfo(tvqConfInfoSubBlock * cfg,int bits0[],int bits1[],int variableBits,INDEX * index,sh_audio_t * sh)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
GetBseInfo(tvqConfInfo * cf,tvqConfInfoSubBlock * cfg,INDEX * index,sh_audio_t * sh)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
GetGainInfo(tvqConfInfo * cf,tvqConfInfoSubBlock * cfg,INDEX * index,sh_audio_t * sh)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
GetLspInfo(tvqConfInfo * cf,INDEX * index,sh_audio_t * sh)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
GetPpcInfo(tvqConfInfo * cf,INDEX * index,sh_audio_t * sh)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;
368
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 }
377
378 return bitcount;
379 }
380
GetEbcInfo(tvqConfInfo * cf,tvqConfInfoSubBlock * cfg,INDEX * index,sh_audio_t * sh)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 }
394
395 return bitcount;
396 }
397
vqf_read_frame(sh_audio_t * sh,INDEX * index)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;
407
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;
425
426 /* Interleaved vector quantization */
427 bitcount += GetVqInfo( cfg, priv->bits_0[btype], priv->bits_1[btype], variableBits, index, sh );
428
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 }
443
444 return bitcount == numFixedBitsPerFrame ? bitcount/8 : 0;
445 }
446
frtobuf_s16(float out[],short bufout[],unsigned frameSize,unsigned numChannels)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;
456
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
frtobuf_float(float out[],float bufout[],unsigned frameSize,unsigned numChannels)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;
483
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
decode_audio(sh_audio_t * sh_audio,unsigned char * buf,int minlen,int maxlen)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 }
526