Mercurial > mplayer.hg
changeset 14276:fa80ed52127b
TwinVQ decoder and demuxer
author | rtognimp |
---|---|
date | Wed, 29 Dec 2004 19:51:56 +0000 |
parents | de13fd557440 |
children | 58f3a6ce6ff3 |
files | etc/codecs.conf libmpcodecs/Makefile libmpcodecs/ad.c libmpcodecs/ad_twin.c libmpcodecs/vqf.h libmpdemux/Makefile libmpdemux/demux_vqf.c libmpdemux/demuxer.c libmpdemux/demuxer.h |
diffstat | 9 files changed, 976 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/etc/codecs.conf Wed Dec 29 19:50:44 2004 +0000 +++ b/etc/codecs.conf Wed Dec 29 19:51:56 2004 +0000 @@ -2475,3 +2475,10 @@ format 0x1104 ; SBC driver acm dll "lhacm.acm" + +audiocodec TwinVQ + info "VQF codec by NTTLabs" + status working + fourcc TWIN + driver vqf + dll "tvqdec.dll"
--- a/libmpcodecs/Makefile Wed Dec 29 19:50:44 2004 +0000 +++ b/libmpcodecs/Makefile Wed Dec 29 19:51:56 2004 +0000 @@ -6,7 +6,7 @@ AUDIO_SRCS_LIB=ad_liba52.c ad_hwac3.c ad_mp3lib.c AUDIO_SRCS_NAT=ad_alaw.c ad_dk3adpcm.c ad_pcm.c ad_dvdpcm.c ad_imaadpcm.c ad_msadpcm.c ad_msgsm.c ad_ra1428.c -AUDIO_SRCS_OPT=ad_acm.c ad_dshow.c ad_dmo.c ad_qtaudio.c ad_ffmpeg.c ad_faad.c ad_libvorbis.c ad_libmad.c ad_realaud.c ad_libdv.c +AUDIO_SRCS_OPT=ad_acm.c ad_dshow.c ad_dmo.c ad_qtaudio.c ad_ffmpeg.c ad_faad.c ad_libvorbis.c ad_libmad.c ad_realaud.c ad_libdv.c ad_twin.c AUDIO_SRCS=dec_audio.c ad.c $(AUDIO_SRCS_LIB) $(AUDIO_SRCS_NAT) $(AUDIO_SRCS_OPT) VIDEO_SRCS_LIB=vd_libmpeg2.c vd_nuv.c vd_lzo.c
--- a/libmpcodecs/ad.c Wed Dec 29 19:50:44 2004 +0000 +++ b/libmpcodecs/ad.c Wed Dec 29 19:51:56 2004 +0000 @@ -38,6 +38,7 @@ extern ad_functions_t mpcodecs_ad_libdv; extern ad_functions_t mpcodecs_ad_qtaudio; extern ad_functions_t mpcodecs_ad_ra1428; +extern ad_functions_t mpcodecs_ad_twin; ad_functions_t* mpcodecs_ad_drivers[] = { @@ -65,6 +66,7 @@ &mpcodecs_ad_dmo, #endif &mpcodecs_ad_acm, + &mpcodecs_ad_twin, #endif #if defined(USE_QTX_CODECS) || defined(MACOSX) &mpcodecs_ad_qtaudio,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpcodecs/ad_twin.c Wed Dec 29 19:51:56 2004 +0000 @@ -0,0 +1,510 @@ +#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", + nbits, BITS_INT); + exit(1); + } + retval = bread(tmpbit, sizeof(*tmpbit), nbits, sh); + for (ibit=retval; ibit<nbits; ibit++){ + tmpbit[ibit] = 0; + } + mask = 0x1<<(nbits-1); + work=0; + for ( ibit=0; ibit<nbits; ibit++ ){ + work += mask*tmpbit[ibit]; + mask >>= 1; + } + *data = work; + return(retval); +} + +static int GetVqInfo( tvqConfInfoSubBlock *cfg, + int bits0[], + int bits1[], + int variableBits, + INDEX *index, + sh_audio_t *sh) +{ + int idiv; + int bitcount = 0; + + if ( index->btype == BLK_LONG ){ + TvqUpdateVectorInfo( variableBits, &cfg->ndiv, bits0, bits1 ); // re-calculate VQ bits + } + for ( idiv=0; idiv<cfg->ndiv; idiv++ ){ + bitcount += get_bstm(&index->wvq[idiv],bits0[idiv],sh); /* CB 0 */ + bitcount += get_bstm(&index->wvq[idiv+cfg->ndiv],bits1[idiv],sh); /* CB 1 */ + } + return bitcount; +} + +static int GetBseInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh) +{ + int i_sup, isf, itmp, idiv; + int bitcount = 0; + + for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ + for ( isf=0; isf<cfg->nsf; isf++ ){ + for ( idiv=0; idiv<cfg->fw_ndiv; idiv++ ){ + itmp = idiv + ( isf + i_sup * cfg->nsf ) * cfg->fw_ndiv; + bitcount += get_bstm(&index->fw[itmp],cfg->fw_nbit,sh); + } + } + } + for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ + for ( isf=0; isf<cfg->nsf; isf++ ){ + bitcount += get_bstm(&index->fw_alf[i_sup * cfg->nsf + isf],cf->FW_ARSW_BITS,sh); + } + } + return bitcount; +} + +static int GetGainInfo(tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh ) +{ + int i_sup, iptop, isf; + int bitcount = 0; + + for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ + iptop = ( cfg->nsubg + 1 ) * i_sup; + bitcount += get_bstm(&index->pow[iptop], cf->GAIN_BITS,sh); + for ( isf=0; isf<cfg->nsubg; isf++ ){ + bitcount += get_bstm(&index->pow[iptop+isf+1], cf->SUB_GAIN_BITS,sh); + } + } + return bitcount; +} + +static int GetLspInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh ) +{ + int i_sup, itmp; + int bitcount = 0; + + for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ + bitcount += get_bstm(&index->lsp[i_sup][0], cf->LSP_BIT0,sh); /* pred. switch */ + bitcount += get_bstm(&index->lsp[i_sup][1], cf->LSP_BIT1,sh); /* first stage */ + for ( itmp=0; itmp<cf->LSP_SPLIT; itmp++ ){ /* second stage */ + bitcount += get_bstm(&index->lsp[i_sup][itmp+2], cf->LSP_BIT2,sh); + } + } + + return bitcount; +} + +static int GetPpcInfo( tvqConfInfo *cf, INDEX *index, sh_audio_t *sh) +{ + int idiv, i_sup; + int bitcount = 0; + vqf_priv_t*priv=sh->context; + + for ( idiv=0; idiv<cf->N_DIV_P; idiv++ ){ + bitcount += get_bstm(&(index->pls[idiv]), priv->bits_0[BLK_PPC][idiv],sh); /*CB0*/ + bitcount += get_bstm(&(index->pls[idiv+cf->N_DIV_P]), priv->bits_1[BLK_PPC][idiv],sh);/*CB1*/ + } + for (i_sup=0; i_sup<cf->N_CH; i_sup++){ + bitcount += get_bstm(&(index->pit[i_sup]), cf->BASF_BIT,sh); + bitcount += get_bstm(&(index->pgain[i_sup]), cf->PGAIN_BIT,sh); + } + + return bitcount; +} + +static int GetEbcInfo( tvqConfInfo *cf, tvqConfInfoSubBlock *cfg, INDEX *index, sh_audio_t *sh) +{ + int i_sup, isf, itmp; + int bitcount = 0; + + for ( i_sup=0; i_sup<cf->N_CH; i_sup++ ){ + for ( isf=0; isf<cfg->nsf; isf++){ + int indexSfOffset = isf * ( cfg->ncrb - cfg->ebc_crb_base ) - cfg->ebc_crb_base; + for ( itmp=cfg->ebc_crb_base; itmp<cfg->ncrb; itmp++ ){ + bitcount += get_bstm(&index->bc[i_sup][itmp+indexSfOffset], cfg->ebc_bits,sh); + } + } + } + + return bitcount; +} + +static int vqf_read_frame(sh_audio_t *sh,INDEX *index) +{ + /*--- Variables ---*/ + tvqConfInfoSubBlock *cfg; + int variableBits; + int bitcount; + int numFixedBitsPerFrame = TvqGetNumFixedBitsPerFrame(); + int btype; + vqf_priv_t *priv=sh->context; + + /*--- Initialization ---*/ + variableBits = 0; + bitcount = 0; + + /*--- read block independent factors ---*/ + /* Window type */ + bitcount += get_bstm( &index->w_type, priv->cf.BITS_WTYPE, sh ); + if ( TvqWtypeToBtype( index->w_type, &index->btype ) ) { + mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error: unknown window type: %d\n", index->w_type); + return 0; + } + btype = index->btype; + + /*--- read block dependent factors ---*/ + cfg = &priv->cf.cfg[btype]; // set the block dependent paremeters table + + bitcount += variableBits; + + /* Interleaved vector quantization */ + bitcount += GetVqInfo( cfg, priv->bits_0[btype], priv->bits_1[btype], variableBits, index, sh ); + + /* Bark-scale envelope */ + bitcount += GetBseInfo( &priv->cf, cfg, index, sh ); + /* Gain */ + bitcount += GetGainInfo( &priv->cf, cfg, index, sh ); + /* LSP */ + bitcount += GetLspInfo( &priv->cf, index, sh ); + /* PPC */ + if ( cfg->ppc_enable ){ + bitcount += GetPpcInfo( &priv->cf, index, sh ); + } + /* Energy Balance Calibration */ + if ( cfg->ebc_enable ){ + bitcount += GetEbcInfo( &priv->cf, cfg, index, sh ); + } + + return bitcount == numFixedBitsPerFrame ? bitcount/8 : 0; +} + +static void frtobuf_s16(float out[], /* Input --- input data frame */ + short bufout[], /* Output --- output data buffer array */ + unsigned frameSize, /* Input --- frame size */ + unsigned numChannels) /* Input --- number of channels */ +{ + /*--- Variables ---*/ + unsigned ismp, ich; + float *ptr; + float dtmp; + + for ( ich=0; ich<numChannels; ich++ ){ + ptr = out+ich*frameSize; + for ( ismp=0; ismp<frameSize; ismp++ ){ + dtmp = ptr[ismp]; + if ( dtmp >= 0. ) { + if ( dtmp > 32700. ) + dtmp = 32700.; + bufout[ismp*numChannels+ich] = (short)(dtmp+0.5); + } else { + if ( dtmp < -32700. ) + dtmp = -32700.; + bufout[ismp*numChannels+ich] = (short)(dtmp-0.5); + } + } + } +} + +static void frtobuf_float(float out[], /* Input --- input data frame */ + float bufout[], /* Output --- output data buffer array */ + unsigned frameSize, /* Input --- frame size */ + unsigned numChannels) /* Input --- number of channels */ +{ + /*--- Variables ---*/ + unsigned ismp, ich; + float *ptr; + float dtmp; + + for ( ich=0; ich<numChannels; ich++ ){ + ptr = out+ich*frameSize; + for ( ismp=0; ismp<frameSize; ismp++ ){ + dtmp = ptr[ismp]; + if ( dtmp >= 0. ) { + if ( dtmp > 32700. ) + dtmp = 32700.; + bufout[ismp*numChannels+ich] = dtmp/32767.; + } else { + if ( dtmp < -32700. ) + dtmp = -32700.; + bufout[ismp*numChannels+ich] = dtmp/32767.; + } + } + } +} + +int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) +{ + int l, len=0; + vqf_priv_t *priv=sh_audio->context; + while(len<minlen) + { + float out[priv->framesize*sh_audio->channels]; + l=vqf_read_frame(sh_audio,&priv->index); + if(!l) break; + TvqDecodeFrame(&priv->index, out); + if (priv->skip_cnt) { + // Ingnore first two frames, replace them with silence + priv->skip_cnt--; + memset(buf, 0, priv->framesize*sh_audio->channels*sh_audio->samplesize); + } else { + if (sh_audio->sample_format == AF_FORMAT_S16_NE) + frtobuf_s16(out, (short *)buf, priv->framesize, sh_audio->channels); + else + frtobuf_float(out, (float *)buf, priv->framesize, sh_audio->channels); + } + len += priv->framesize*sh_audio->channels*sh_audio->samplesize; + buf += priv->framesize*sh_audio->channels*sh_audio->samplesize; + } + return len; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpcodecs/vqf.h Wed Dec 29 19:51:56 2004 +0000 @@ -0,0 +1,226 @@ +/* (c)Copyright 1996-2000 NTT Cyber Space Laboratories */ +/* Released on 2000.05.22 by N. Iwakami */ +/* Modified on 2000.05.25 by N. Iwakami */ +/* Released on 2000.09.06 by N. Iwakami */ + +// Modified for MPlayer on 2004.12.29 + +#ifndef tvqdec_h +#define tvqdec_h + +#ifdef _MSC_VER +# ifdef DLL_MODULE +# define DllPort __declspec( dllexport ) +# else +# define DllPort __declspec( dllimport ) +# endif +#else +# define DllPort +#endif + +#ifdef __cplusplus +extern "C" { // only need to import/export C interface if used by C++ source code +#endif + +/************************/ +/*** General settings ***/ +/************************/ +/* Initialization error code */ +enum INIT_ERROR_CODE { + TVQ_NO_ERROR = 0, // no error + TVQ_ERROR, // general + TVQ_ERROR_VERSION, // wrong version + TVQ_ERROR_CHANNEL, // channel setting error + TVQ_ERROR_MODE, // wrong coding mode + TVQ_ERROR_PARAM, // inner parameter setting error + TVQ_ERROR_N_CAN, // wrong number of VQ pre-selection candidates, used only in encoder +}; + +/* version ID */ +#define TVQ_UNKNOWN_VERSION -1 +#define V2 0 +#define V2PP 1 + +#define N_VERSIONS 2 + +/* window types */ +enum WINDOW_TYPE { + ONLY_LONG_WINDOW = 0, + LONG_SHORT_WINDOW, + ONLY_SHORT_WINDOW, + SHORT_LONG_WINDOW, + SHORT_MEDIUM_WINDOW, + MEDIUM_LONG_WINDOW, + LONG_MEDIUM_WINDOW, + MEDIUM_SHORT_WINDOW, + ONLY_MEDIUM_WINDOW, +}; + +/* block types */ +enum BLOCK_TYPE { + BLK_SHORT = 0, + BLK_MEDIUM, + BLK_LONG, + BLK_PPC, +}; +#define N_BTYPE 3 // number of block types +#define N_INTR_TYPE 4 // number of interleave types, enum BLOCK_TYPE is commonly used for detecting interleave types. + +/* maximum number of channels */ +#define N_CH_MAX 2 + +/* type definition of code information interface */ +typedef struct { + /* block type */ + int w_type; + int btype; + + /* FBC info */ + int *segment_sw[ N_CH_MAX ]; + int *band_sw[ N_CH_MAX ]; + int *fg_intensity[ N_CH_MAX ]; + + /* VQ info */ + int *wvq; + + /* BSE info */ + int *fw; + int *fw_alf; + + /* gain info */ + int *pow; + + /* LSP info */ + int *lsp[ N_CH_MAX ]; + + /* PPC info */ + int pit[ N_CH_MAX ]; + int *pls; + int pgain[ N_CH_MAX ]; + + /* EBC info */ + int *bc[ N_CH_MAX ]; + + void *manager; +} INDEX; + +/***********************************************/ +/*** Definitions about program configuration ***/ +/***********************************************/ +/* type definition of tvqConfInfoSubBlock */ +typedef struct { + int sf_sz; // subframe size + int nsf; // number of subframes + int ndiv; // number of division of weighted interleave vector quantization + int ncrb; // number of Bark-scale subbands + int fw_ndiv; // number of division of BSE VQ + int fw_nbit; // number of bits for BSE VQ + int nsubg; // number of sub-blocks for gain coding + int ppc_enable; // PPC switch + int ebc_enable; // EBC switch + int ebc_crb_base; // EBC base band + int ebc_bits; // EBC bits + int fbc_enable; // FBC switch + int fbc_n_segment; // FBC number of segments + int fbc_nband; // FBC number of subbands + int *fbc_crb_tbl; // FBC subband table +} tvqConfInfoSubBlock; + +/* type definition of tvqConfInfo */ +typedef struct { + /* frame configuration */ + int N_CH; + /* window type coding */ + int BITS_WTYPE; + /* LSP coding */ + int LSP_BIT0; + int LSP_BIT1; + int LSP_BIT2; + int LSP_SPLIT; + /* Bark-scale envelope coding */ + int FW_ARSW_BITS; + /* gain coding */ + int GAIN_BITS; + int SUB_GAIN_BITS; + /* pitch excitation */ + int N_DIV_P; + int BASF_BIT; + int PGAIN_BIT; + + /* block type dependent parameters */ + tvqConfInfoSubBlock cfg[N_BTYPE]; + +} tvqConfInfo; + + +/*************************************************/ +/*** Definitions about TwinVQ bitstream header ***/ +/*************************************************/ +//#include "../declib_src/tvq_hdr.h" +//#ifndef BUFSIZ +//#define BUFSIZ 1024 +//#endif + +#define KEYWORD_BYTES 4 +#define VERSION_BYTES 8 +#define ELEM_BYTES sizeof(unsigned long) + + +/* + */ +typedef struct { + char ID[KEYWORD_BYTES+VERSION_BYTES+1]; + int size; + /* Common Chunk */ + int channelMode; /* channel mode (mono:0/stereo:1) */ + int bitRate; /* bit rate (kbit/s) */ + int samplingRate; /* sampling rate (44.1 kHz -> 44) */ + int securityLevel; /* security level (always 0) */ + /* Text Chunk */ + char Name[BUFSIZ]; + char Comt[BUFSIZ]; + char Auth[BUFSIZ]; + char Cpyr[BUFSIZ]; + char File[BUFSIZ]; + char Extr[BUFSIZ]; // add by OKAMOTO 99.12.21 + /* Data size chunk*/ + int Dsiz; +} headerInfo; + +// TwinVQ decoder initialization/termination functions +//DllPort int TvqInitialize( headerInfo *setupInfo, INDEX *index, int dispErrorMessageBox ); +//DllPort void TvqTerminate( INDEX *index ); +//DllPort void TvqGetVectorInfo(int *bits0[], int *bits1[]); +//DllPort void TvqResetFrameCounter(); + +// TwinVQ decoder function +//DllPort void TvqDecodeFrame(INDEX *indexp, float out[]); +//DllPort int TvqWtypeToBtype( int w_type, int *btype ); +//DllPort void TvqUpdateVectorInfo(int varbits, int *ndiv, int bits0[], int bits1[]); +//DllPort void TvqSetFrameCounter( int position ); + +// TwinVQ query functions +//DllPort int TvqCheckVersion(char *versionID); +//DllPort void TvqGetSetupInfo(headerInfo *setupInfo); // setup information +//DllPort void TvqGetConfInfo(tvqConfInfo *cf); // configuration information +//DllPort int TvqGetFrameSize(); // frame size +//DllPort int TvqGetNumChannels(); // number of channels +//DllPort int TvqGetBitRate(); // total bitrate +//DllPort float TvqGetSamplingRate(); // sampling rate +//DllPort int TvqGetNumFixedBitsPerFrame(); // number of fixed bits per frame +//DllPort int TvqGetNumFrames(); // number of decoded frame +//DllPort int TvqGetModuleVersion( char* versionString ); + +#ifdef V2PLUS_SUPPORT +// TwinVQ FB coding tool control +DllPort void TvqFbCountUsedBits(int nbit); // count number of used bits +DllPort float TvqGetFbCurrentBitrate(); // query average bitrate for the tool +DllPort int TvqGetFbTotalBits(); // query total number of used bits +#endif + +#ifdef __cplusplus +} +#endif + + +#endif
--- a/libmpdemux/Makefile Wed Dec 29 19:50:44 2004 +0000 +++ b/libmpdemux/Makefile Wed Dec 29 19:51:56 2004 +0000 @@ -3,7 +3,7 @@ include ../config.mak -SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_ty.c demux_ty_osd.c demux_pva.c demux_viv.c demuxer.c dvdnav_stream.c open.c parse_es.c stream.c stream_file.c stream_netstream.c stream_vcd.c stream_null.c stream_ftp.c tv.c tvi_dummy.c tvi_v4l.c tvi_v4l2.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c cdda.c demux_rawaudio.c demux_rawvideo.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_alsa1x.c ai_oss.c audio_in.c demux_smjpeg.c demux_lmlm4.c cue_read.c extension.c demux_gif.c demux_ts.c demux_realaud.c url.c muxer_rawvideo.c demux_lavf.c demux_nsv.c +SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_ty.c demux_ty_osd.c demux_pva.c demux_viv.c demuxer.c dvdnav_stream.c open.c parse_es.c stream.c stream_file.c stream_netstream.c stream_vcd.c stream_null.c stream_ftp.c tv.c tvi_dummy.c tvi_v4l.c tvi_v4l2.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c cdda.c demux_rawaudio.c demux_rawvideo.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_alsa1x.c ai_oss.c audio_in.c demux_smjpeg.c demux_lmlm4.c cue_read.c extension.c demux_gif.c demux_ts.c demux_realaud.c url.c muxer_rawvideo.c demux_lavf.c demux_nsv.c demux_vqf.c ifeq ($(XMMS_PLUGINS),yes) SRCS += demux_xmms.c endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpdemux/demux_vqf.c Wed Dec 29 19:51:56 2004 +0000 @@ -0,0 +1,201 @@ +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include "bswap.h" + +#include "stream.h" +#include "demuxer.h" +#include "stheader.h" +#include "../libmpcodecs/vqf.h" + +extern void resync_audio_stream(sh_audio_t *sh_audio); + +int demux_probe_vqf(demuxer_t* demuxer) +{ + char buf[KEYWORD_BYTES]; + stream_t *s; + s = demuxer->stream; + stream_read(s,buf,KEYWORD_BYTES); + if(memcmp(buf,"TWIN",KEYWORD_BYTES)==0) return 1; /*version: 97012000*/ + return 0; +} + +demuxer_t* demux_open_vqf(demuxer_t* demuxer) { + sh_audio_t* sh_audio; + WAVEFORMATEX* w; + stream_t *s; + headerInfo *hi; + + s = demuxer->stream; + + sh_audio = new_sh_audio(demuxer,0); + sh_audio->wf = w = (WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX)+sizeof(headerInfo)); + hi = (headerInfo *)&w[1]; + memset(hi,0,sizeof(headerInfo)); + w->wFormatTag = 0x1; + sh_audio->format = mmioFOURCC('T','W','I','N'); /* TWinVQ */ + w->nChannels = sh_audio->channels = 2; + w->nSamplesPerSec = sh_audio->samplerate = 44100; + w->nAvgBytesPerSec = w->nSamplesPerSec*sh_audio->channels*2; + w->nBlockAlign = 0; + sh_audio->samplesize = 2; + w->wBitsPerSample = 8*sh_audio->samplesize; + w->cbSize = 0; + strcpy(hi->ID,"TWIN"); + stream_read(s,hi->ID+KEYWORD_BYTES,VERSION_BYTES); /* fourcc+version_id */ + while(1) + { + char chunk_id[4]; + unsigned chunk_size; + hi->size=chunk_size=stream_read_dword(s); /* include itself */ + stream_read(s,chunk_id,4); + if(*((uint32_t *)&chunk_id[0])==mmioFOURCC('C','O','M','M')) + { + char buf[chunk_size-8]; + unsigned i,subchunk_size; + if(stream_read(s,buf,chunk_size-8)!=chunk_size-8) return NULL; + i=0; + subchunk_size=be2me_32(*((uint32_t *)&buf[0])); + hi->channelMode=be2me_32(*((uint32_t *)&buf[4])); + w->nChannels=sh_audio->channels=hi->channelMode+1; /*0-mono;1-stereo*/ + hi->bitRate=be2me_32(*((uint32_t *)&buf[8])); + sh_audio->i_bps=hi->bitRate*1000/8; /* bitrate kbit/s */ + w->nAvgBytesPerSec = sh_audio->i_bps; + hi->samplingRate=be2me_32(*((uint32_t *)&buf[12])); + switch(hi->samplingRate){ + case 44: + w->nSamplesPerSec=44100; + break; + case 22: + w->nSamplesPerSec=22050; + break; + case 11: + w->nSamplesPerSec=11025; + break; + default: + w->nSamplesPerSec=hi->samplingRate*1000; + break; + } + sh_audio->samplerate=w->nSamplesPerSec; + hi->securityLevel=be2me_32(*((uint32_t *)&buf[16])); + w->nBlockAlign = 0; + sh_audio->samplesize = 4; + w->wBitsPerSample = 8*sh_audio->samplesize; + w->cbSize = 0; + i+=subchunk_size+4; + while(i<chunk_size-8) + { + unsigned slen,sid; + char sdata[chunk_size]; + sid=*((uint32_t *)&buf[i]); i+=4; + slen=be2me_32(*((uint32_t *)&buf[i])); i+=4; + if(sid==mmioFOURCC('D','S','I','Z')) + { + hi->Dsiz=be2me_32(*((uint32_t *)&buf[i])); + continue; /* describes the same info as size of DATA chunk */ + } + memcpy(sdata,&buf[i],slen); sdata[slen]=0; i+=slen; + if(sid==mmioFOURCC('N','A','M','E')) + { + memcpy(hi->Name,sdata,min(BUFSIZ,slen)); + demux_info_add(demuxer,"Title",sdata); + } + else + if(sid==mmioFOURCC('A','U','T','H')) + { + memcpy(hi->Auth,sdata,min(BUFSIZ,slen)); + demux_info_add(demuxer,"Author",sdata); + } + else + if(sid==mmioFOURCC('C','O','M','T')) + { + memcpy(hi->Comt,sdata,min(BUFSIZ,slen)); + demux_info_add(demuxer,"Comment",sdata); + } + else + if(sid==mmioFOURCC('(','c',')',' ')) + { + memcpy(hi->Cpyr,sdata,min(BUFSIZ,slen)); + demux_info_add(demuxer,"Copyright",sdata); + } + else + if(sid==mmioFOURCC('F','I','L','E')) + { + memcpy(hi->File,sdata,min(BUFSIZ,slen)); + } + else + if(sid==mmioFOURCC('A','L','B','M')) demux_info_add(demuxer,"Album",sdata); + else + if(sid==mmioFOURCC('Y','E','A','R')) demux_info_add(demuxer,"Date",sdata); + else + if(sid==mmioFOURCC('T','R','A','C')) demux_info_add(demuxer,"Track",sdata); + else + if(sid==mmioFOURCC('E','N','C','D')) demux_info_add(demuxer,"Encoder",sdata); + else + mp_msg(MSGT_DEMUX, MSGL_V, "Unhandled subchunk '%c%c%c%c'='%s'\n",((char *)&sid)[0],((char *)&sid)[1],((char *)&sid)[2],((char *)&sid)[3],sdata); + /* other stuff is unrecognized due untranslatable japan's idiomatics */ + } + } + else + if(*((uint32_t *)&chunk_id[0])==mmioFOURCC('D','A','T','A')) + { + demuxer->movi_start=stream_tell(s); + demuxer->movi_end=demuxer->movi_start+chunk_size-8; + mp_msg(MSGT_DEMUX, MSGL_V, "Found data at %llX size %llu\n",demuxer->movi_start,demuxer->movi_end); + /* Done! play it */ + break; + } + else + { + mp_msg(MSGT_DEMUX, MSGL_V, "Unhandled chunk '%c%c%c%c' %u bytes\n",((char *)&chunk_id)[0],((char *)&chunk_id)[1],((char *)&chunk_id)[2],((char *)&chunk_id)[3],chunk_size); + stream_skip(s,chunk_size-8); /*unknown chunk type */ + } + } + + demuxer->audio->sh = sh_audio; + sh_audio->ds = demuxer->audio; + stream_seek(s,demuxer->movi_start); + demuxer->seekable=0; + return demuxer; +} + +int demux_vqf_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) { + sh_audio_t* sh_audio = demuxer->audio->sh; + int l = sh_audio->wf->nAvgBytesPerSec; + off_t spos = stream_tell(demuxer->stream); + demux_packet_t* dp; + + if(stream_eof(demuxer->stream)) + return 0; + + dp = new_demux_packet(l); + ds->pts = spos / (float)(sh_audio->wf->nAvgBytesPerSec); + ds->pos = spos; + + l=stream_read(demuxer->stream,dp->buffer,l); + resize_demux_packet(dp,l); + ds_add_packet(ds,dp); + + return 1; +} + +void demux_seek_vqf(demuxer_t *demuxer,float rel_seek_secs,int flags){ +#if 0 + stream_t* s = demuxer->stream; + sh_audio_t* sh_audio = demuxer->audio->sh; + off_t base,pos; + + base = (flags & 1) ? demuxer->movi_start : stream_tell(s); + if(flags & 2) + pos = base + ((demuxer->movi_end - demuxer->movi_start)*rel_seek_secs); + else + pos = base + (rel_seek_secs*sh_audio->i_bps); + + pos -= (pos % (sh_audio->channels * sh_audio->samplesize) ); + stream_seek(s,pos); + resync_audio_stream(sh_audio); +#endif +} + +void demux_close_vqf(demuxer_t* demuxer) {}
--- a/libmpdemux/demuxer.c Wed Dec 29 19:50:44 2004 +0000 +++ b/libmpdemux/demuxer.c Wed Dec 29 19:51:56 2004 +0000 @@ -156,6 +156,7 @@ extern void demux_close_ra(demuxer_t* demuxer); extern void demux_close_ty(demuxer_t* demuxer); extern void demux_close_lavf(demuxer_t* demuxer); +extern void demux_close_vqf(demuxer_t* demuxer); #ifdef USE_TV @@ -241,6 +242,8 @@ demux_close_mpg(demuxer); break; case DEMUXER_TYPE_REALAUDIO: demux_close_ra(demuxer); break; + case DEMUXER_TYPE_VQF: + demux_close_vqf(demuxer); break; #ifdef USE_LIBAVFORMAT case DEMUXER_TYPE_LAVF: demux_close_lavf(demuxer); break; @@ -326,6 +329,7 @@ int demux_gif_fill_buffer(demuxer_t *demux); int demux_ts_fill_buffer(demuxer_t *demux); int demux_ra_fill_buffer(demuxer_t *demux); +int demux_vqf_fill_buffer(demuxer_t *demux); extern int demux_demuxers_fill_buffer(demuxer_t *demux,demux_stream_t *ds); extern int demux_ogg_fill_buffer(demuxer_t *d); @@ -390,6 +394,7 @@ case DEMUXER_TYPE_MPEG_TS: return demux_ts_fill_buffer(demux); case DEMUXER_TYPE_REALAUDIO: return demux_ra_fill_buffer(demux); + case DEMUXER_TYPE_VQF: return demux_vqf_fill_buffer(demux); #ifdef USE_LIBAVFORMAT case DEMUXER_TYPE_LAVF: return demux_lavf_fill_buffer(demux); #endif @@ -634,6 +639,8 @@ extern int demux_open_mkv(demuxer_t *demuxer); extern int ra_check_file(demuxer_t *demuxer); extern int demux_open_ra(demuxer_t* demuxer); +extern int demux_probe_vqf(demuxer_t *demuxer); +extern int demux_open_vqf(demuxer_t* demuxer); #ifdef HAVE_MATROSKA extern int demux_mkv_open(demuxer_t *demuxer); #endif @@ -809,6 +816,18 @@ } } +//=============== Try to open as VQF file: ================= +if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_VQF){ + demuxer=new_demuxer(stream,DEMUXER_TYPE_VQF,audio_id,video_id,dvdsub_id); + if(demux_probe_vqf(demuxer)){ + mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"VQF"); + file_format=DEMUXER_TYPE_VQF; + } else { + free_demuxer(demuxer); + demuxer = NULL; + } +} + //=============== Try based on filename EXTENSION: ================= // Ok. We're over the stable detectable fileformats, the next ones are a bit // fuzzy. So by default (extension_parsing==1) try extension-based detection @@ -1355,6 +1374,10 @@ if (!demux_open_ra(demuxer)) return NULL; break; } + case DEMUXER_TYPE_VQF: { + if (!demux_open_vqf(demuxer)) return NULL; + break; + } #ifdef USE_LIBAVFORMAT case DEMUXER_TYPE_LAVF: { if (!demux_open_lavf(demuxer)) return NULL; @@ -1474,6 +1497,7 @@ extern void demux_rawvideo_seek(demuxer_t *demuxer,float rel_seek_secs,int flags); extern void demux_xmms_seek(demuxer_t *demuxer,float rel_seek_secs,int flags); extern void demux_mkv_seek(demuxer_t *demuxer,float rel_seek_secs,int flags); +extern void demux_seek_vqf(demuxer_t *demuxer,float rel_seek_secs,int flags); int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){ demux_stream_t *d_audio=demuxer->audio; @@ -1576,6 +1600,8 @@ case DEMUXER_TYPE_LAVF: demux_seek_lavf(demuxer,rel_seek_secs,flags); break; #endif + case DEMUXER_TYPE_VQF: + demux_seek_vqf(demuxer,rel_seek_secs,flags); break; } // switch(demuxer->file_format)
--- a/libmpdemux/demuxer.h Wed Dec 29 19:50:44 2004 +0000 +++ b/libmpdemux/demuxer.h Wed Dec 29 19:51:56 2004 +0000 @@ -44,11 +44,12 @@ #define DEMUXER_TYPE_LMLM4 34 #define DEMUXER_TYPE_LAVF 35 #define DEMUXER_TYPE_NSV 36 +#define DEMUXER_TYPE_VQF 37 // This should always match the higest demuxer type number. // Unless you want to disallow users to force the demuxer to some types #define DEMUXER_TYPE_MIN 0 -#define DEMUXER_TYPE_MAX 36 +#define DEMUXER_TYPE_MAX 37 #define DEMUXER_TYPE_DEMUXERS (1<<16) // A virtual demuxer type for the network code