Add support for VDPAU video out, including hardware decoding.
[mplayer/glamo.git] / libmpcodecs / ad_twin.c
blob01d68a38cd9921de422d36bc0839c7b332116a1a
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include "config.h"
6 #include "ad_internal.h"
7 #include "vqf.h"
8 #include "loader/ldt_keeper.h"
9 #include "loader/wine/windef.h"
10 #include "libaf/af_format.h"
12 #include "help_mp.h"
14 static ad_info_t info =
16 "TWinVQ decoder",
17 "vqf",
18 "Roberto Togni",
19 "Nick Kurshev",
20 "Ported from MPlayerXP"
23 LIBAD_EXTERN(twin)
25 void* WINAPI LoadLibraryA(char* name);
26 void* WINAPI GetProcAddress(void* handle, char* func);
27 int WINAPI FreeLibrary(void* handle);
29 static int (*TvqInitialize)( headerInfo *setupInfo, INDEX *index, int dispErrorMessageBox );
30 static void (*TvqTerminate)( INDEX *index );
31 static void (*TvqGetVectorInfo)(int *bits0[], int *bits1[]);
33 static void (*TvqDecodeFrame)(INDEX *indexp, float out[]);
34 static int (*TvqWtypeToBtype)( int w_type, int *btype );
35 static void (*TvqUpdateVectorInfo)(int varbits, int *ndiv, int bits0[], int bits1[]);
37 static int (*TvqCheckVersion)(char *versionID);
38 static void (*TvqGetConfInfo)(tvqConfInfo *cf);
39 static int (*TvqGetFrameSize)();
40 static int (*TvqGetNumFixedBitsPerFrame)();
42 #define BYTE_BIT 8
43 #define BBUFSIZ 1024 /* Bit buffer size (bytes) */
44 #define BBUFLEN (BBUFSIZ*BYTE_BIT) /* Bit buffer length (bits) */
45 typedef struct vqf_priv_s
47 float pts;
48 WAVEFORMATEX o_wf; // out format
49 INDEX index;
50 tvqConfInfo cf;
51 headerInfo hi;
52 int *bits_0[N_INTR_TYPE], *bits_1[N_INTR_TYPE];
53 unsigned framesize;
54 /* stream related */
55 int readable;
56 int ptr; /* current point in the bit buffer */
57 int nbuf; /* bit buffer size */
58 char buf[BBUFSIZ]; /* the bit buffer */
59 int skip_cnt;
60 }vqf_priv_t;
62 static void* vqf_dll;
64 static int load_dll( char *libname )
66 #ifdef WIN32_LOADER
67 Setup_LDT_Keeper();
68 #endif
69 vqf_dll = LoadLibraryA(libname);
70 if( vqf_dll == NULL )
72 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "failed loading dll\n" );
73 return 0;
75 TvqInitialize = GetProcAddress(vqf_dll,"TvqInitialize");
76 TvqTerminate = GetProcAddress(vqf_dll,"TvqTerminate");
77 TvqGetVectorInfo = GetProcAddress(vqf_dll,"TvqGetVectorInfo");
78 TvqDecodeFrame = GetProcAddress(vqf_dll,"TvqDecodeFrame");
79 TvqWtypeToBtype = GetProcAddress(vqf_dll,"TvqWtypeToBtype");
80 TvqUpdateVectorInfo = GetProcAddress(vqf_dll,"TvqUpdateVectorInfo");
81 TvqCheckVersion = GetProcAddress(vqf_dll,"TvqCheckVersion");
82 TvqGetConfInfo = GetProcAddress(vqf_dll,"TvqGetConfInfo");
83 TvqGetFrameSize = GetProcAddress(vqf_dll,"TvqGetFrameSize");
84 TvqGetNumFixedBitsPerFrame = GetProcAddress(vqf_dll,"TvqGetNumFixedBitsPerFrame");
85 return TvqInitialize && TvqTerminate && TvqGetVectorInfo &&
86 TvqDecodeFrame && TvqWtypeToBtype && TvqUpdateVectorInfo &&
87 TvqCheckVersion && TvqGetConfInfo && TvqGetFrameSize &&
88 TvqGetNumFixedBitsPerFrame;
91 void print_wave_header(WAVEFORMATEX *h, int verbose_level);
92 static int init_vqf_audio_codec(sh_audio_t *sh_audio){
93 WAVEFORMATEX *in_fmt=sh_audio->wf;
94 vqf_priv_t*priv=sh_audio->context;
95 int ver;
96 mp_msg(MSGT_DECAUDIO, MSGL_INFO, "======= Win32 (TWinVQ) AUDIO Codec init =======\n");
98 sh_audio->channels=in_fmt->nChannels;
99 sh_audio->samplerate=in_fmt->nSamplesPerSec;
100 sh_audio->sample_format=AF_FORMAT_S16_NE;
101 // sh_audio->sample_format=AF_FORMAT_FLOAT_NE;
102 sh_audio->samplesize=af_fmt2bits(sh_audio->sample_format)/8;
103 priv->o_wf.nChannels=in_fmt->nChannels;
104 priv->o_wf.nSamplesPerSec=in_fmt->nSamplesPerSec;
105 priv->o_wf.nBlockAlign=sh_audio->samplesize*in_fmt->nChannels;
106 priv->o_wf.nAvgBytesPerSec=in_fmt->nBlockAlign*in_fmt->nChannels;
107 priv->o_wf.wFormatTag=0x01;
108 priv->o_wf.wBitsPerSample=in_fmt->wBitsPerSample;
109 priv->o_wf.cbSize=0;
111 if( mp_msg_test(MSGT_DECAUDIO,MSGL_V) )
113 mp_msg(MSGT_DECAUDIO, MSGL_V, "Input format:\n");
114 print_wave_header(in_fmt, MSGL_V);
115 mp_msg(MSGT_DECAUDIO, MSGL_V, "Output fmt:\n");
116 print_wave_header(&priv->o_wf, MSGL_V);
118 memcpy(&priv->hi,&in_fmt[1],sizeof(headerInfo));
119 if((ver=TvqInitialize(&priv->hi,&priv->index,0))){
120 const char *tvqe[]={
121 "No errors",
122 "General error",
123 "Wrong version",
124 "Channel setting error",
125 "Wrong coding mode",
126 "Inner parameter setting error",
127 "Wrong number of VQ pre-selection candidates, used only in encoder" };
128 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq initialization error: %s\n",ver>=0&&ver<7?tvqe[ver]:"Unknown");
129 return 0;
131 ver=TvqCheckVersion(priv->hi.ID);
132 if(ver==TVQ_UNKNOWN_VERSION){
133 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq unknown version of stream\n" );
134 return 0;
136 TvqGetConfInfo(&priv->cf);
137 TvqGetVectorInfo(priv->bits_0,priv->bits_1);
138 priv->framesize=TvqGetFrameSize();
139 sh_audio->audio_in_minsize=priv->framesize*in_fmt->nChannels;
140 sh_audio->a_in_buffer_size=4*sh_audio->audio_in_minsize;
141 sh_audio->a_in_buffer=av_malloc(sh_audio->a_in_buffer_size);
142 sh_audio->a_in_buffer_len=0;
145 return 1;
148 static int close_vqf_audio_codec(sh_audio_t *sh_audio)
150 vqf_priv_t*priv=sh_audio->context;
151 TvqTerminate(&priv->index);
152 return 1;
155 int init(sh_audio_t *sh_audio)
157 return 1;
160 int preinit(sh_audio_t *sh_audio)
162 /* Win32 VQF audio codec: */
163 vqf_priv_t *priv;
164 if(!(sh_audio->context=malloc(sizeof(vqf_priv_t)))) return 0;
165 priv=sh_audio->context;
166 if(!load_dll(sh_audio->codec->dll))
168 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "win32.dll looks broken :(\n");
169 return 0;
171 if(!init_vqf_audio_codec(sh_audio)){
172 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "TWinVQ initialization fail\n");
173 return 0;
175 mp_msg(MSGT_DECAUDIO, MSGL_INFO, "INFO: TWinVQ (%s) audio codec init OK!\n",sh_audio->codec->dll);
176 priv->skip_cnt = 2;
177 return 1;
180 void uninit(sh_audio_t *sh)
182 close_vqf_audio_codec(sh);
183 free(sh->context);
184 FreeLibrary(vqf_dll);
187 int control(sh_audio_t *sh_audio,int cmd,void* arg, ...)
189 switch(cmd) {
190 case ADCTRL_QUERY_FORMAT:
191 return CONTROL_TRUE;
192 default:
193 return CONTROL_UNKNOWN;
197 static int bread(char *data, /* Output: Output data array */
198 int size, /* Input: Length of each data */
199 int nbits, /* Input: Number of bits to write */
200 sh_audio_t *sh) /* Input: File pointer */
202 /*--- Variables ---*/
203 int ibits, iptr, idata, ibufadr, ibufbit, icl;
204 unsigned char mask, tmpdat;
205 int retval;
206 vqf_priv_t *priv=sh->context;
208 /*--- Main operation ---*/
209 retval = 0;
210 mask = 0x1;
211 for ( ibits=0; ibits<nbits; ibits++ ){
212 if ( priv->readable == 0 ){ /* when the file data buffer is empty */
213 priv->nbuf = demux_read_data(sh->ds, priv->buf, BBUFSIZ);
214 priv->nbuf *= 8;
215 priv->readable = 1;
217 iptr = priv->ptr; /* current file data buffer pointer */
218 if ( iptr >= priv->nbuf ) /* If data file is empty then return */
219 return retval;
220 ibufadr = iptr/BYTE_BIT; /* current file data buffer address */
221 ibufbit = iptr%BYTE_BIT; /* current file data buffer bit */
222 /* tmpdat = stream->buf[ibufadr] >> (BYTE_BIT-ibufbit-1); */
223 tmpdat = (unsigned char)priv->buf[ibufadr];
224 tmpdat >>= (BYTE_BIT-ibufbit-1);
225 /* current data bit */
227 idata = ibits*size; /* output data address */
228 data[idata] = (char)(tmpdat & mask); /* set output data */
229 for (icl=1; icl<size; icl++)
230 data[idata+icl] = 0; /* clear the rest output data buffer */
231 priv->ptr += 1; /* update data buffer pointer */
232 if (priv->ptr == BBUFLEN){
233 priv->ptr = 0;
234 priv->readable = 0;
236 ++retval;
238 return retval;
241 #define BITS_INT (sizeof(int)*8)
243 static int get_bstm(int *data, /* Input: input data */
244 unsigned nbits, /* Input: number of bits */
245 sh_audio_t *sh) /* Input: bit file pointer */
247 unsigned ibit;
248 unsigned mask;
249 unsigned work;
250 char tmpbit[BITS_INT];
251 int retval;
253 if ( nbits > BITS_INT ){
254 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "get_bstm(): %d: %d Error.\n",
255 nbits, BITS_INT);
256 exit(1);
258 retval = bread(tmpbit, sizeof(*tmpbit), nbits, sh);
259 for (ibit=retval; ibit<nbits; ibit++){
260 tmpbit[ibit] = 0;
262 mask = 0x1<<(nbits-1);
263 work=0;
264 for ( ibit=0; ibit<nbits; ibit++ ){
265 work += mask*tmpbit[ibit];
266 mask >>= 1;
268 *data = work;
269 return retval;
272 static int GetVqInfo( tvqConfInfoSubBlock *cfg,
273 int bits0[],
274 int bits1[],
275 int variableBits,
276 INDEX *index,
277 sh_audio_t *sh)
279 int idiv;
280 int bitcount = 0;
282 if ( index->btype == BLK_LONG ){
283 TvqUpdateVectorInfo( variableBits, &cfg->ndiv, bits0, bits1 ); // re-calculate VQ bits
285 for ( idiv=0; idiv<cfg->ndiv; idiv++ ){
286 bitcount += get_bstm(&index->wvq[idiv],bits0[idiv],sh); /* CB 0 */
287 bitcount += get_bstm(&index->wvq[idiv+cfg->ndiv],bits1[idiv],sh); /* CB 1 */
289 return bitcount;
292 static int GetBseInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh)
294 int i_sup, isf, itmp, idiv;
295 int bitcount = 0;
297 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
298 for ( isf=0; isf<cfg->nsf; isf++ ){
299 for ( idiv=0; idiv<cfg->fw_ndiv; idiv++ ){
300 itmp = idiv + ( isf + i_sup * cfg->nsf ) * cfg->fw_ndiv;
301 bitcount += get_bstm(&index->fw[itmp],cfg->fw_nbit,sh);
305 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
306 for ( isf=0; isf<cfg->nsf; isf++ ){
307 bitcount += get_bstm(&index->fw_alf[i_sup * cfg->nsf + isf],cf->FW_ARSW_BITS,sh);
310 return bitcount;
313 static int GetGainInfo(tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh )
315 int i_sup, iptop, isf;
316 int bitcount = 0;
318 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
319 iptop = ( cfg->nsubg + 1 ) * i_sup;
320 bitcount += get_bstm(&index->pow[iptop], cf->GAIN_BITS,sh);
321 for ( isf=0; isf<cfg->nsubg; isf++ ){
322 bitcount += get_bstm(&index->pow[iptop+isf+1], cf->SUB_GAIN_BITS,sh);
325 return bitcount;
328 static int GetLspInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh )
330 int i_sup, itmp;
331 int bitcount = 0;
333 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
334 bitcount += get_bstm(&index->lsp[i_sup][0], cf->LSP_BIT0,sh); /* pred. switch */
335 bitcount += get_bstm(&index->lsp[i_sup][1], cf->LSP_BIT1,sh); /* first stage */
336 for ( itmp=0; itmp<cf->LSP_SPLIT; itmp++ ){ /* second stage */
337 bitcount += get_bstm(&index->lsp[i_sup][itmp+2], cf->LSP_BIT2,sh);
341 return bitcount;
344 static int GetPpcInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh)
346 int idiv, i_sup;
347 int bitcount = 0;
348 vqf_priv_t*priv=sh->context;
350 for ( idiv=0; idiv<cf->N_DIV_P; idiv++ ){
351 bitcount += get_bstm(&(index->pls[idiv]), priv->bits_0[BLK_PPC][idiv],sh); /*CB0*/
352 bitcount += get_bstm(&(index->pls[idiv+cf->N_DIV_P]), priv->bits_1[BLK_PPC][idiv],sh);/*CB1*/
354 for (i_sup=0; i_sup<cf->N_CH; i_sup++){
355 bitcount += get_bstm(&(index->pit[i_sup]), cf->BASF_BIT,sh);
356 bitcount += get_bstm(&(index->pgain[i_sup]), cf->PGAIN_BIT,sh);
359 return bitcount;
362 static int GetEbcInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh)
364 int i_sup, isf, itmp;
365 int bitcount = 0;
367 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
368 for ( isf=0; isf<cfg->nsf; isf++){
369 int indexSfOffset = isf * ( cfg->ncrb - cfg->ebc_crb_base ) - cfg->ebc_crb_base;
370 for ( itmp=cfg->ebc_crb_base; itmp<cfg->ncrb; itmp++ ){
371 bitcount += get_bstm(&index->bc[i_sup][itmp+indexSfOffset], cfg->ebc_bits,sh);
376 return bitcount;
379 static int vqf_read_frame(sh_audio_t *sh,INDEX *index)
381 /*--- Variables ---*/
382 tvqConfInfoSubBlock *cfg;
383 int variableBits;
384 int bitcount;
385 int numFixedBitsPerFrame = TvqGetNumFixedBitsPerFrame();
386 int btype;
387 vqf_priv_t *priv=sh->context;
389 /*--- Initialization ---*/
390 variableBits = 0;
391 bitcount = 0;
393 /*--- read block independent factors ---*/
394 /* Window type */
395 bitcount += get_bstm( &index->w_type, priv->cf.BITS_WTYPE, sh );
396 if ( TvqWtypeToBtype( index->w_type, &index->btype ) ) {
397 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error: unknown window type: %d\n", index->w_type);
398 return 0;
400 btype = index->btype;
402 /*--- read block dependent factors ---*/
403 cfg = &priv->cf.cfg[btype]; // set the block dependent paremeters table
405 bitcount += variableBits;
407 /* Interleaved vector quantization */
408 bitcount += GetVqInfo( cfg, priv->bits_0[btype], priv->bits_1[btype], variableBits, index, sh );
410 /* Bark-scale envelope */
411 bitcount += GetBseInfo( &priv->cf, cfg, index, sh );
412 /* Gain */
413 bitcount += GetGainInfo( &priv->cf, cfg, index, sh );
414 /* LSP */
415 bitcount += GetLspInfo( &priv->cf, index, sh );
416 /* PPC */
417 if ( cfg->ppc_enable ){
418 bitcount += GetPpcInfo( &priv->cf, index, sh );
420 /* Energy Balance Calibration */
421 if ( cfg->ebc_enable ){
422 bitcount += GetEbcInfo( &priv->cf, cfg, index, sh );
425 return bitcount == numFixedBitsPerFrame ? bitcount/8 : 0;
428 static void frtobuf_s16(float out[], /* Input --- input data frame */
429 short bufout[], /* Output --- output data buffer array */
430 unsigned frameSize, /* Input --- frame size */
431 unsigned numChannels) /* Input --- number of channels */
433 /*--- Variables ---*/
434 unsigned ismp, ich;
435 float *ptr;
436 float dtmp;
438 for ( ich=0; ich<numChannels; ich++ ){
439 ptr = out+ich*frameSize;
440 for ( ismp=0; ismp<frameSize; ismp++ ){
441 dtmp = ptr[ismp];
442 if ( dtmp >= 0. ) {
443 if ( dtmp > 32700. )
444 dtmp = 32700.;
445 bufout[ismp*numChannels+ich] = (short)(dtmp+0.5);
446 } else {
447 if ( dtmp < -32700. )
448 dtmp = -32700.;
449 bufout[ismp*numChannels+ich] = (short)(dtmp-0.5);
455 static void frtobuf_float(float out[], /* Input --- input data frame */
456 float bufout[], /* Output --- output data buffer array */
457 unsigned frameSize, /* Input --- frame size */
458 unsigned numChannels) /* Input --- number of channels */
460 /*--- Variables ---*/
461 unsigned ismp, ich;
462 float *ptr;
463 float dtmp;
465 for ( ich=0; ich<numChannels; ich++ ){
466 ptr = out+ich*frameSize;
467 for ( ismp=0; ismp<frameSize; ismp++ ){
468 dtmp = ptr[ismp];
469 if ( dtmp >= 0. ) {
470 if ( dtmp > 32700. )
471 dtmp = 32700.;
472 bufout[ismp*numChannels+ich] = dtmp/32767.;
473 } else {
474 if ( dtmp < -32700. )
475 dtmp = -32700.;
476 bufout[ismp*numChannels+ich] = dtmp/32767.;
482 int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
484 int l, len=0;
485 vqf_priv_t *priv=sh_audio->context;
486 while(len<minlen)
488 float out[priv->framesize*sh_audio->channels];
489 l=vqf_read_frame(sh_audio,&priv->index);
490 if(!l) break;
491 TvqDecodeFrame(&priv->index, out);
492 if (priv->skip_cnt) {
493 // Ingnore first two frames, replace them with silence
494 priv->skip_cnt--;
495 memset(buf, 0, priv->framesize*sh_audio->channels*sh_audio->samplesize);
496 } else {
497 if (sh_audio->sample_format == AF_FORMAT_S16_NE)
498 frtobuf_s16(out, (short *)buf, priv->framesize, sh_audio->channels);
499 else
500 frtobuf_float(out, (float *)buf, priv->framesize, sh_audio->channels);
502 len += priv->framesize*sh_audio->channels*sh_audio->samplesize;
503 buf += priv->framesize*sh_audio->channels*sh_audio->samplesize;
505 return len;