cocoa_common: add HiDPI/retina support
[mplayer.git] / libmpcodecs / ad_twin.c
blob9aa304e4fc8fc5164448ee888d9e7c8be17b4836
1 /*
2 * This file is part of MPlayer.
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.
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.
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.
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include "config.h"
24 #include "ad_internal.h"
25 #include "vqf.h"
26 #include "libmpdemux/aviprint.h"
27 #include "loader/ldt_keeper.h"
28 #include "loader/wine/windef.h"
29 #include "libaf/af_format.h"
32 static const ad_info_t info =
34 "TWinVQ decoder",
35 "vqf",
36 "Roberto Togni",
37 "Nick Kurshev",
38 "Ported from MPlayerXP"
41 LIBAD_EXTERN(twin)
43 void* WINAPI LoadLibraryA(char* name);
44 void* WINAPI GetProcAddress(void* handle, char* func);
45 int WINAPI FreeLibrary(void* handle);
47 static int (*TvqInitialize)( headerInfo *setupInfo, INDEX *index, int dispErrorMessageBox );
48 static void (*TvqTerminate)( INDEX *index );
49 static void (*TvqGetVectorInfo)(int *bits0[], int *bits1[]);
51 static void (*TvqDecodeFrame)(INDEX *indexp, float out[]);
52 static int (*TvqWtypeToBtype)( int w_type, int *btype );
53 static void (*TvqUpdateVectorInfo)(int varbits, int *ndiv, int bits0[], int bits1[]);
55 static int (*TvqCheckVersion)(char *versionID);
56 static void (*TvqGetConfInfo)(tvqConfInfo *cf);
57 static int (*TvqGetFrameSize)(void);
58 static int (*TvqGetNumFixedBitsPerFrame)(void);
60 #define BYTE_BIT 8
61 #define BBUFSIZ 1024 /* Bit buffer size (bytes) */
62 #define BBUFLEN (BBUFSIZ*BYTE_BIT) /* Bit buffer length (bits) */
63 typedef struct vqf_priv_s
65 float pts;
66 WAVEFORMATEX o_wf; // out format
67 INDEX index;
68 tvqConfInfo cf;
69 headerInfo hi;
70 int *bits_0[N_INTR_TYPE], *bits_1[N_INTR_TYPE];
71 unsigned framesize;
72 /* stream related */
73 int readable;
74 int ptr; /* current point in the bit buffer */
75 int nbuf; /* bit buffer size */
76 char buf[BBUFSIZ]; /* the bit buffer */
77 int skip_cnt;
78 }vqf_priv_t;
80 static void* vqf_dll;
82 static int load_dll( char *libname )
84 #ifdef WIN32_LOADER
85 Setup_LDT_Keeper();
86 #endif
87 vqf_dll = LoadLibraryA(libname);
88 if( vqf_dll == NULL )
90 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "failed loading dll\n" );
91 return 0;
93 TvqInitialize = GetProcAddress(vqf_dll,"TvqInitialize");
94 TvqTerminate = GetProcAddress(vqf_dll,"TvqTerminate");
95 TvqGetVectorInfo = GetProcAddress(vqf_dll,"TvqGetVectorInfo");
96 TvqDecodeFrame = GetProcAddress(vqf_dll,"TvqDecodeFrame");
97 TvqWtypeToBtype = GetProcAddress(vqf_dll,"TvqWtypeToBtype");
98 TvqUpdateVectorInfo = GetProcAddress(vqf_dll,"TvqUpdateVectorInfo");
99 TvqCheckVersion = GetProcAddress(vqf_dll,"TvqCheckVersion");
100 TvqGetConfInfo = GetProcAddress(vqf_dll,"TvqGetConfInfo");
101 TvqGetFrameSize = GetProcAddress(vqf_dll,"TvqGetFrameSize");
102 TvqGetNumFixedBitsPerFrame = GetProcAddress(vqf_dll,"TvqGetNumFixedBitsPerFrame");
103 return TvqInitialize && TvqTerminate && TvqGetVectorInfo &&
104 TvqDecodeFrame && TvqWtypeToBtype && TvqUpdateVectorInfo &&
105 TvqCheckVersion && TvqGetConfInfo && TvqGetFrameSize &&
106 TvqGetNumFixedBitsPerFrame;
109 static int init_vqf_audio_codec(sh_audio_t *sh_audio){
110 WAVEFORMATEX *in_fmt=sh_audio->wf;
111 vqf_priv_t*priv=sh_audio->context;
112 int ver;
113 mp_msg(MSGT_DECAUDIO, MSGL_INFO, "======= Win32 (TWinVQ) AUDIO Codec init =======\n");
115 sh_audio->channels=in_fmt->nChannels;
116 sh_audio->samplerate=in_fmt->nSamplesPerSec;
117 sh_audio->sample_format=AF_FORMAT_S16_NE;
118 // sh_audio->sample_format=AF_FORMAT_FLOAT_NE;
119 sh_audio->samplesize=af_fmt2bits(sh_audio->sample_format)/8;
120 priv->o_wf.nChannels=in_fmt->nChannels;
121 priv->o_wf.nSamplesPerSec=in_fmt->nSamplesPerSec;
122 priv->o_wf.nBlockAlign=sh_audio->samplesize*in_fmt->nChannels;
123 priv->o_wf.nAvgBytesPerSec=in_fmt->nBlockAlign*in_fmt->nChannels;
124 priv->o_wf.wFormatTag=0x01;
125 priv->o_wf.wBitsPerSample=in_fmt->wBitsPerSample;
126 priv->o_wf.cbSize=0;
128 if( mp_msg_test(MSGT_DECAUDIO,MSGL_V) )
130 mp_msg(MSGT_DECAUDIO, MSGL_V, "Input format:\n");
131 print_wave_header(in_fmt, MSGL_V);
132 mp_msg(MSGT_DECAUDIO, MSGL_V, "Output fmt:\n");
133 print_wave_header(&priv->o_wf, MSGL_V);
135 memcpy(&priv->hi,&in_fmt[1],sizeof(headerInfo));
136 if((ver=TvqInitialize(&priv->hi,&priv->index,0))){
137 const char *tvqe[]={
138 "No errors",
139 "General error",
140 "Wrong version",
141 "Channel setting error",
142 "Wrong coding mode",
143 "Inner parameter setting error",
144 "Wrong number of VQ pre-selection candidates, used only in encoder" };
145 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq initialization error: %s\n",ver>=0&&ver<7?tvqe[ver]:"Unknown");
146 return 0;
148 ver=TvqCheckVersion(priv->hi.ID);
149 if(ver==TVQ_UNKNOWN_VERSION){
150 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq unknown version of stream\n" );
151 return 0;
153 TvqGetConfInfo(&priv->cf);
154 TvqGetVectorInfo(priv->bits_0,priv->bits_1);
155 priv->framesize=TvqGetFrameSize();
156 sh_audio->audio_in_minsize=priv->framesize*in_fmt->nChannels;
157 sh_audio->a_in_buffer_size=4*sh_audio->audio_in_minsize;
158 sh_audio->a_in_buffer=av_malloc(sh_audio->a_in_buffer_size);
159 sh_audio->a_in_buffer_len=0;
162 return 1;
165 static int close_vqf_audio_codec(sh_audio_t *sh_audio)
167 vqf_priv_t*priv=sh_audio->context;
168 TvqTerminate(&priv->index);
169 return 1;
172 int init(sh_audio_t *sh_audio)
174 return 1;
177 int preinit(sh_audio_t *sh_audio)
179 /* Win32 VQF audio codec: */
180 vqf_priv_t *priv;
181 if(!(sh_audio->context=malloc(sizeof(vqf_priv_t)))) return 0;
182 priv=sh_audio->context;
183 if(!load_dll(sh_audio->codec->dll))
185 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "win32.dll looks broken :(\n");
186 return 0;
188 if(!init_vqf_audio_codec(sh_audio)){
189 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "TWinVQ initialization fail\n");
190 return 0;
192 mp_msg(MSGT_DECAUDIO, MSGL_INFO, "INFO: TWinVQ (%s) audio codec init OK!\n",sh_audio->codec->dll);
193 priv->skip_cnt = 2;
194 return 1;
197 void uninit(sh_audio_t *sh)
199 close_vqf_audio_codec(sh);
200 free(sh->context);
201 FreeLibrary(vqf_dll);
204 static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...)
206 switch(cmd) {
207 case ADCTRL_QUERY_FORMAT:
208 return CONTROL_TRUE;
209 default:
210 return CONTROL_UNKNOWN;
214 static int bread(char *data, /* Output: Output data array */
215 int size, /* Input: Length of each data */
216 int nbits, /* Input: Number of bits to write */
217 sh_audio_t *sh) /* Input: File pointer */
219 /*--- Variables ---*/
220 int ibits, iptr, idata, ibufadr, ibufbit, icl;
221 unsigned char mask, tmpdat;
222 int retval;
223 vqf_priv_t *priv=sh->context;
225 /*--- Main operation ---*/
226 retval = 0;
227 mask = 0x1;
228 for ( ibits=0; ibits<nbits; ibits++ ){
229 if ( priv->readable == 0 ){ /* when the file data buffer is empty */
230 priv->nbuf = demux_read_data(sh->ds, priv->buf, BBUFSIZ);
231 priv->nbuf *= 8;
232 priv->readable = 1;
234 iptr = priv->ptr; /* current file data buffer pointer */
235 if ( iptr >= priv->nbuf ) /* If data file is empty then return */
236 return retval;
237 ibufadr = iptr/BYTE_BIT; /* current file data buffer address */
238 ibufbit = iptr%BYTE_BIT; /* current file data buffer bit */
239 /* tmpdat = stream->buf[ibufadr] >> (BYTE_BIT-ibufbit-1); */
240 tmpdat = (unsigned char)priv->buf[ibufadr];
241 tmpdat >>= (BYTE_BIT-ibufbit-1);
242 /* current data bit */
244 idata = ibits*size; /* output data address */
245 data[idata] = (char)(tmpdat & mask); /* set output data */
246 for (icl=1; icl<size; icl++)
247 data[idata+icl] = 0; /* clear the rest output data buffer */
248 priv->ptr += 1; /* update data buffer pointer */
249 if (priv->ptr == BBUFLEN){
250 priv->ptr = 0;
251 priv->readable = 0;
253 ++retval;
255 return retval;
258 #define BITS_INT (sizeof(int)*8)
260 static int get_bstm(int *data, /* Input: input data */
261 unsigned nbits, /* Input: number of bits */
262 sh_audio_t *sh) /* Input: bit file pointer */
264 unsigned ibit;
265 unsigned mask;
266 unsigned work;
267 char tmpbit[BITS_INT];
268 int retval;
270 if ( nbits > BITS_INT ){
271 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "get_bstm(): %d: %d Error.\n",
272 nbits, BITS_INT);
273 exit(1);
275 retval = bread(tmpbit, sizeof(*tmpbit), nbits, sh);
276 for (ibit=retval; ibit<nbits; ibit++){
277 tmpbit[ibit] = 0;
279 mask = 0x1<<(nbits-1);
280 work=0;
281 for ( ibit=0; ibit<nbits; ibit++ ){
282 work += mask*tmpbit[ibit];
283 mask >>= 1;
285 *data = work;
286 return retval;
289 static int GetVqInfo( tvqConfInfoSubBlock *cfg,
290 int bits0[],
291 int bits1[],
292 int variableBits,
293 INDEX *index,
294 sh_audio_t *sh)
296 int idiv;
297 int bitcount = 0;
299 if ( index->btype == BLK_LONG ){
300 TvqUpdateVectorInfo( variableBits, &cfg->ndiv, bits0, bits1 ); // re-calculate VQ bits
302 for ( idiv=0; idiv<cfg->ndiv; idiv++ ){
303 bitcount += get_bstm(&index->wvq[idiv],bits0[idiv],sh); /* CB 0 */
304 bitcount += get_bstm(&index->wvq[idiv+cfg->ndiv],bits1[idiv],sh); /* CB 1 */
306 return bitcount;
309 static int GetBseInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh)
311 int i_sup, isf, itmp, idiv;
312 int bitcount = 0;
314 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
315 for ( isf=0; isf<cfg->nsf; isf++ ){
316 for ( idiv=0; idiv<cfg->fw_ndiv; idiv++ ){
317 itmp = idiv + ( isf + i_sup * cfg->nsf ) * cfg->fw_ndiv;
318 bitcount += get_bstm(&index->fw[itmp],cfg->fw_nbit,sh);
322 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
323 for ( isf=0; isf<cfg->nsf; isf++ ){
324 bitcount += get_bstm(&index->fw_alf[i_sup * cfg->nsf + isf],cf->FW_ARSW_BITS,sh);
327 return bitcount;
330 static int GetGainInfo(tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh )
332 int i_sup, iptop, isf;
333 int bitcount = 0;
335 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
336 iptop = ( cfg->nsubg + 1 ) * i_sup;
337 bitcount += get_bstm(&index->pow[iptop], cf->GAIN_BITS,sh);
338 for ( isf=0; isf<cfg->nsubg; isf++ ){
339 bitcount += get_bstm(&index->pow[iptop+isf+1], cf->SUB_GAIN_BITS,sh);
342 return bitcount;
345 static int GetLspInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh )
347 int i_sup, itmp;
348 int bitcount = 0;
350 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
351 bitcount += get_bstm(&index->lsp[i_sup][0], cf->LSP_BIT0,sh); /* pred. switch */
352 bitcount += get_bstm(&index->lsp[i_sup][1], cf->LSP_BIT1,sh); /* first stage */
353 for ( itmp=0; itmp<cf->LSP_SPLIT; itmp++ ){ /* second stage */
354 bitcount += get_bstm(&index->lsp[i_sup][itmp+2], cf->LSP_BIT2,sh);
358 return bitcount;
361 static int GetPpcInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh)
363 int idiv, i_sup;
364 int bitcount = 0;
365 vqf_priv_t*priv=sh->context;
367 for ( idiv=0; idiv<cf->N_DIV_P; idiv++ ){
368 bitcount += get_bstm(&(index->pls[idiv]), priv->bits_0[BLK_PPC][idiv],sh); /*CB0*/
369 bitcount += get_bstm(&(index->pls[idiv+cf->N_DIV_P]), priv->bits_1[BLK_PPC][idiv],sh);/*CB1*/
371 for (i_sup=0; i_sup<cf->N_CH; i_sup++){
372 bitcount += get_bstm(&(index->pit[i_sup]), cf->BASF_BIT,sh);
373 bitcount += get_bstm(&(index->pgain[i_sup]), cf->PGAIN_BIT,sh);
376 return bitcount;
379 static int GetEbcInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh)
381 int i_sup, isf, itmp;
382 int bitcount = 0;
384 for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){
385 for ( isf=0; isf<cfg->nsf; isf++){
386 int indexSfOffset = isf * ( cfg->ncrb - cfg->ebc_crb_base ) - cfg->ebc_crb_base;
387 for ( itmp=cfg->ebc_crb_base; itmp<cfg->ncrb; itmp++ ){
388 bitcount += get_bstm(&index->bc[i_sup][itmp+indexSfOffset], cfg->ebc_bits,sh);
393 return bitcount;
396 static int vqf_read_frame(sh_audio_t *sh,INDEX *index)
398 /*--- Variables ---*/
399 tvqConfInfoSubBlock *cfg;
400 int variableBits;
401 int bitcount;
402 int numFixedBitsPerFrame = TvqGetNumFixedBitsPerFrame();
403 int btype;
404 vqf_priv_t *priv=sh->context;
406 /*--- Initialization ---*/
407 variableBits = 0;
408 bitcount = 0;
410 /*--- read block independent factors ---*/
411 /* Window type */
412 bitcount += get_bstm( &index->w_type, priv->cf.BITS_WTYPE, sh );
413 if ( TvqWtypeToBtype( index->w_type, &index->btype ) ) {
414 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error: unknown window type: %d\n", index->w_type);
415 return 0;
417 btype = index->btype;
419 /*--- read block dependent factors ---*/
420 cfg = &priv->cf.cfg[btype]; // set the block dependent paremeters table
422 bitcount += variableBits;
424 /* Interleaved vector quantization */
425 bitcount += GetVqInfo( cfg, priv->bits_0[btype], priv->bits_1[btype], variableBits, index, sh );
427 /* Bark-scale envelope */
428 bitcount += GetBseInfo( &priv->cf, cfg, index, sh );
429 /* Gain */
430 bitcount += GetGainInfo( &priv->cf, cfg, index, sh );
431 /* LSP */
432 bitcount += GetLspInfo( &priv->cf, index, sh );
433 /* PPC */
434 if ( cfg->ppc_enable ){
435 bitcount += GetPpcInfo( &priv->cf, index, sh );
437 /* Energy Balance Calibration */
438 if ( cfg->ebc_enable ){
439 bitcount += GetEbcInfo( &priv->cf, cfg, index, sh );
442 return bitcount == numFixedBitsPerFrame ? bitcount/8 : 0;
445 static void frtobuf_s16(float out[], /* Input --- input data frame */
446 short bufout[], /* Output --- output data buffer array */
447 unsigned frameSize, /* Input --- frame size */
448 unsigned numChannels) /* Input --- number of channels */
450 /*--- Variables ---*/
451 unsigned ismp, ich;
452 float *ptr;
453 float dtmp;
455 for ( ich=0; ich<numChannels; ich++ ){
456 ptr = out+ich*frameSize;
457 for ( ismp=0; ismp<frameSize; ismp++ ){
458 dtmp = ptr[ismp];
459 if ( dtmp >= 0. ) {
460 if ( dtmp > 32700. )
461 dtmp = 32700.;
462 bufout[ismp*numChannels+ich] = (short)(dtmp+0.5);
463 } else {
464 if ( dtmp < -32700. )
465 dtmp = -32700.;
466 bufout[ismp*numChannels+ich] = (short)(dtmp-0.5);
472 static void frtobuf_float(float out[], /* Input --- input data frame */
473 float bufout[], /* Output --- output data buffer array */
474 unsigned frameSize, /* Input --- frame size */
475 unsigned numChannels) /* Input --- number of channels */
477 /*--- Variables ---*/
478 unsigned ismp, ich;
479 float *ptr;
480 float dtmp;
482 for ( ich=0; ich<numChannels; ich++ ){
483 ptr = out+ich*frameSize;
484 for ( ismp=0; ismp<frameSize; ismp++ ){
485 dtmp = ptr[ismp];
486 if ( dtmp >= 0. ) {
487 if ( dtmp > 32700. )
488 dtmp = 32700.;
489 bufout[ismp*numChannels+ich] = dtmp/32767.;
490 } else {
491 if ( dtmp < -32700. )
492 dtmp = -32700.;
493 bufout[ismp*numChannels+ich] = dtmp/32767.;
499 int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
501 int l, len=0;
502 vqf_priv_t *priv=sh_audio->context;
503 while(len<minlen)
505 float out[priv->framesize*sh_audio->channels];
506 l=vqf_read_frame(sh_audio,&priv->index);
507 if(!l) break;
508 TvqDecodeFrame(&priv->index, out);
509 if (priv->skip_cnt) {
510 // Ingnore first two frames, replace them with silence
511 priv->skip_cnt--;
512 memset(buf, 0, priv->framesize*sh_audio->channels*sh_audio->samplesize);
513 } else {
514 if (sh_audio->sample_format == AF_FORMAT_S16_NE)
515 frtobuf_s16(out, (short *)buf, priv->framesize, sh_audio->channels);
516 else
517 frtobuf_float(out, (float *)buf, priv->framesize, sh_audio->channels);
519 len += priv->framesize*sh_audio->channels*sh_audio->samplesize;
520 buf += priv->framesize*sh_audio->channels*sh_audio->samplesize;
522 return len;