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