📄 ad_twin.c
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include "config.h"#ifdef USE_WIN32DLL#include "ad_internal.h"#include "vqf.h"#include "../../loader/ldt_keeper.h"#include "wine/windef.h"#include "../libaf/af_format.h"#include "help_mp.h"static ad_info_t info = { "TWinVQ decoder", "vqf", "Roberto Togni", "Nick Kurshev", "Ported from MPlayerXP"};LIBAD_EXTERN(twin)void* WINAPI LoadLibraryA(char* name);void* WINAPI GetProcAddress(void* handle, char* func);int WINAPI FreeLibrary(void* handle);static int (*TvqInitialize)( headerInfo *setupInfo, INDEX *index, int dispErrorMessageBox );static void (*TvqTerminate)( INDEX *index );static void (*TvqGetVectorInfo)(int *bits0[], int *bits1[]);static void (*TvqDecodeFrame)(INDEX *indexp, float out[]);static int (*TvqWtypeToBtype)( int w_type, int *btype );static void (*TvqUpdateVectorInfo)(int varbits, int *ndiv, int bits0[], int bits1[]);static int (*TvqCheckVersion)(char *versionID);static void (*TvqGetConfInfo)(tvqConfInfo *cf);static int (*TvqGetFrameSize)();static int (*TvqGetNumFixedBitsPerFrame)();#define BYTE_BIT 8#define BBUFSIZ 1024 /* Bit buffer size (bytes) */#define BBUFLEN (BBUFSIZ*BYTE_BIT) /* Bit buffer length (bits) */typedef struct vqf_priv_s{ float pts; WAVEFORMATEX o_wf; // out format INDEX index; tvqConfInfo cf; headerInfo hi; int *bits_0[N_INTR_TYPE], *bits_1[N_INTR_TYPE]; unsigned framesize; /* stream related */ int readable; int ptr; /* current point in the bit buffer */ int nbuf; /* bit buffer size */ char buf[BBUFSIZ]; /* the bit buffer */ int skip_cnt;}vqf_priv_t;static void* vqf_dll;static int load_dll( char *libname ){#ifdef WIN32_LOADER Setup_LDT_Keeper();#endif vqf_dll = LoadLibraryA(libname); if( vqf_dll == NULL ) { mp_msg(MSGT_DECAUDIO, MSGL_ERR, "failed loading dll\n" ); return 0; } TvqInitialize = GetProcAddress(vqf_dll,"TvqInitialize"); TvqTerminate = GetProcAddress(vqf_dll,"TvqTerminate"); TvqGetVectorInfo = GetProcAddress(vqf_dll,"TvqGetVectorInfo"); TvqDecodeFrame = GetProcAddress(vqf_dll,"TvqDecodeFrame"); TvqWtypeToBtype = GetProcAddress(vqf_dll,"TvqWtypeToBtype"); TvqUpdateVectorInfo = GetProcAddress(vqf_dll,"TvqUpdateVectorInfo"); TvqCheckVersion = GetProcAddress(vqf_dll,"TvqCheckVersion"); TvqGetConfInfo = GetProcAddress(vqf_dll,"TvqGetConfInfo"); TvqGetFrameSize = GetProcAddress(vqf_dll,"TvqGetFrameSize"); TvqGetNumFixedBitsPerFrame = GetProcAddress(vqf_dll,"TvqGetNumFixedBitsPerFrame"); return TvqInitialize && TvqTerminate && TvqGetVectorInfo && TvqDecodeFrame && TvqWtypeToBtype && TvqUpdateVectorInfo && TvqCheckVersion && TvqGetConfInfo && TvqGetFrameSize && TvqGetNumFixedBitsPerFrame;}extern void print_wave_header(WAVEFORMATEX *h);static int init_vqf_audio_codec(sh_audio_t *sh_audio){ WAVEFORMATEX *in_fmt=sh_audio->wf; vqf_priv_t*priv=sh_audio->context; int ver; mp_msg(MSGT_DECAUDIO, MSGL_INFO, "======= Win32 (TWinVQ) AUDIO Codec init =======\n"); sh_audio->channels=in_fmt->nChannels; sh_audio->samplerate=in_fmt->nSamplesPerSec; sh_audio->sample_format=AF_FORMAT_S16_NE;// sh_audio->sample_format=AF_FORMAT_FLOAT_NE; sh_audio->samplesize=af_fmt2bits(sh_audio->sample_format)/8; priv->o_wf.nChannels=in_fmt->nChannels; priv->o_wf.nSamplesPerSec=in_fmt->nSamplesPerSec; priv->o_wf.nBlockAlign=sh_audio->samplesize*in_fmt->nChannels; priv->o_wf.nAvgBytesPerSec=in_fmt->nBlockAlign*in_fmt->nChannels; priv->o_wf.wFormatTag=0x01; priv->o_wf.wBitsPerSample=in_fmt->wBitsPerSample; priv->o_wf.cbSize=0; if(verbose) { mp_msg(MSGT_DECAUDIO, MSGL_INFO, "Input format:\n"); print_wave_header(in_fmt); mp_msg(MSGT_DECAUDIO, MSGL_INFO, "Output fmt:\n"); print_wave_header(&priv->o_wf); } memcpy(&priv->hi,&in_fmt[1],sizeof(headerInfo)); if((ver=TvqInitialize(&priv->hi,&priv->index,0))){ const char *tvqe[]={ "No errors", "General error", "Wrong version", "Channel setting error", "Wrong coding mode", "Inner parameter setting error", "Wrong number of VQ pre-selection candidates, used only in encoder" }; mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq initialization error: %s\n",ver>=0&&ver<7?tvqe[ver]:"Unknown"); return 0; } ver=TvqCheckVersion(priv->hi.ID); if(ver==TVQ_UNKNOWN_VERSION){ mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Tvq unknown version of stream\n" ); return 0; } TvqGetConfInfo(&priv->cf); TvqGetVectorInfo(priv->bits_0,priv->bits_1); priv->framesize=TvqGetFrameSize(); sh_audio->audio_in_minsize=priv->framesize*in_fmt->nChannels; sh_audio->a_in_buffer_size=4*sh_audio->audio_in_minsize; sh_audio->a_in_buffer=malloc(sh_audio->a_in_buffer_size); sh_audio->a_in_buffer_len=0; return 1;}static int close_vqf_audio_codec(sh_audio_t *sh_audio){ vqf_priv_t*priv=sh_audio->context; TvqTerminate(&priv->index); return 1;}int init(sh_audio_t *sh_audio){ return 1;}int preinit(sh_audio_t *sh_audio){ /* Win32 VQF audio codec: */ vqf_priv_t *priv; if(!(sh_audio->context=malloc(sizeof(vqf_priv_t)))) return 0; priv=sh_audio->context; if(!load_dll(sh_audio->codec->dll)) { mp_msg(MSGT_DECAUDIO, MSGL_ERR, "win32.dll looks broken :(\n"); return 0; } if(!init_vqf_audio_codec(sh_audio)){ mp_msg(MSGT_DECAUDIO, MSGL_ERR, "TWinVQ initialization fail\n"); return 0; } mp_msg(MSGT_DECAUDIO, MSGL_INFO, "INFO: TWinVQ (%s) audio codec init OK!\n",sh_audio->codec->dll); priv->skip_cnt = 2; return 1;}void uninit(sh_audio_t *sh){ close_vqf_audio_codec(sh); free(sh->context); FreeLibrary(vqf_dll);}int control(sh_audio_t *sh_audio,int cmd,void* arg, ...){ switch(cmd) { case ADCTRL_QUERY_FORMAT: return CONTROL_TRUE; default: return CONTROL_UNKNOWN; }}static int bread(char *data, /* Output: Output data array */ int size, /* Input: Length of each data */ int nbits, /* Input: Number of bits to write */ sh_audio_t *sh) /* Input: File pointer */{ /*--- Variables ---*/ int ibits, iptr, idata, ibufadr, ibufbit, icl; unsigned char mask, tmpdat; int retval; vqf_priv_t *priv=sh->context; /*--- Main operation ---*/ retval = 0; mask = 0x1; for ( ibits=0; ibits<nbits; ibits++ ){ if ( priv->readable == 0 ){ /* when the file data buffer is empty */ priv->nbuf = demux_read_data(sh->ds, priv->buf, BBUFSIZ); priv->nbuf *= 8; priv->readable = 1; } iptr = priv->ptr; /* current file data buffer pointer */ if ( iptr >= priv->nbuf ) /* If data file is empty then return */ return(retval); ibufadr = iptr/BYTE_BIT; /* current file data buffer address */ ibufbit = iptr%BYTE_BIT; /* current file data buffer bit */ /* tmpdat = stream->buf[ibufadr] >> (BYTE_BIT-ibufbit-1); */ tmpdat = (unsigned char)priv->buf[ibufadr]; tmpdat >>= (BYTE_BIT-ibufbit-1); /* current data bit */ idata = ibits*size; /* output data address */ data[idata] = (char)(tmpdat & mask); /* set output data */ for (icl=1; icl<size; icl++) data[idata+icl] = 0; /* clear the rest output data buffer */ priv->ptr += 1; /* update data buffer pointer */ if (priv->ptr == BBUFLEN){ priv->ptr = 0; priv->readable = 0; } ++retval; } return(retval);}#define BITS_INT (sizeof(int)*8)static int get_bstm(int *data, /* Input: input data */ unsigned nbits, /* Input: number of bits */ sh_audio_t *sh) /* Input: bit file pointer */{ unsigned ibit; unsigned mask; unsigned work; char tmpbit[BITS_INT]; int retval; if ( nbits > BITS_INT ){ mp_msg(MSGT_DECAUDIO, MSGL_ERR, "get_bstm(): %d: %d Error.\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -