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