Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Tue, 24 Jan 2012 01:41:53 +0000 (02:41 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Tue, 24 Jan 2012 01:41:53 +0000 (02:41 +0100)
* qatar/master:
  Remove ffmpeg.
  aacenc: Simplify windowing
  aacenc: Move saved overlap samples to the beginning of the same buffer as incoming samples.
  aacenc: Deinterleave input samples before processing.
  aacenc: Store channel count in AACEncContext.
  aacenc: Move Q^3/4 calculation to it's own table
  aacenc: Request normalized float samples instead of converting s16 samples to float.
  aacpsy: Replace an if with FFMAX in LAME windowing.
  aacenc: cosmetics, replace 'rd' with 'bits' in codebook_trellis_rate to make it more clear what is being calculated.
  aacpsy: cosmetics, change a FIXME to a NOTE about subshort comparisons
  aacenc: cosmetics: move init() and end() to the bottom of the file.
  aacenc: aac_encode_init() cleanup
  XWD encoder and decoder
  vc1: don't read the interpfrm and bfraction elements for interlaced frames
  mxfdec: fix memleak on mxf_read_close()
  westwood: split the AUD and VQA demuxers into separate files.

Conflicts:
.gitignore
Changelog
Makefile
configure
doc/ffmpeg.texi
ffmpeg.c
libavcodec/Makefile
libavcodec/aacenc.c
libavcodec/allcodecs.c
libavcodec/avcodec.h
libavcodec/version.h
libavformat/Makefile
libavformat/img2.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
16 files changed:
1  2 
Changelog
doc/general.texi
libavcodec/Makefile
libavcodec/aaccoder.c
libavcodec/aacenc.c
libavcodec/aacenc.h
libavcodec/aacpsy.c
libavcodec/allcodecs.c
libavcodec/avcodec.h
libavcodec/psymodel.c
libavcodec/psymodel.h
libavcodec/vc1.c
libavcodec/version.h
libavformat/Makefile
libavformat/img2.c
libavformat/westwood_vqa.c

diff --cc Changelog
+++ b/Changelog
@@@ -2,41 -2,28 +2,42 @@@ Entries are sorted chronologically fro
  releases are sorted from youngest to oldest.
  
  
 -version 0.8:
 -
 +version next:
 +- v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder
 +- SBaGen (SBG) binaural beats script demuxer
 +- OpenMG Audio muxer
 +- Timecode extraction in DV and MOV
 +- thumbnail video filter
 +- XML output in ffprobe
 +- asplit audio filter
 +- tinterlace video filter
 +- astreamsync audio filter
 +- amerge audio filter
  - GSM audio parser
  - SMJPEG muxer
 -
 -
 -version 0.8_beta2:
 -
+ - XWD encoder and decoder
  - Automatic thread count based on detection number of (available) CPU cores
 -- Deprecate libpostproc. If desired, the switch --enable-postproc will
 -  enable it but it may be removed in a later Libav release.
 +- y41p Brooktree Uncompressed 4:1:1 12-bit encoder and decoder
 +- ffprobe -show_error option
 +- Avid 1:1 10-bit RGB Packer decoder
 +- v308 Quicktime Uncompressed 4:4:4 encoder and decoder
 +- yuv4 libquicktime packed 4:2:0 encoder and decoder
 +- ffprobe -show_frames option
 +- silencedetect audio filter
 +- ffprobe -show_program_version, -show_library_versions, -show_versions options
  - rv34: frame-level multi-threading
  - optimized iMDCT transform on x86 using SSE for for mpegaudiodec
 +- Improved PGS subtitle decoder
  
  
 -version 0.8_beta1:
 +version 0.9:
  
 +- openal input device added
 +- boxblur filter added
  - BWF muxer
  - Flash Screen Video 2 decoder
 -- ffplay/ffprobe/ffserver renamed to avplay/avprobe/avserver
 -- ffmpeg deprecated, added avconv, which is almost the same for now, except
 +- lavfi input device added
 +- added avconv, which is almost the same for now, except
  for a few incompatible changes in the options, which will hopefully make them
  easier to use. The changes are:
      * The options placement is now strictly enforced! While in theory the
Simple merge
@@@ -470,11 -435,9 +470,13 @@@ OBJS-$(CONFIG_XBIN_DECODER)            
  OBJS-$(CONFIG_XL_DECODER)              += xl.o
  OBJS-$(CONFIG_XSUB_DECODER)            += xsubdec.o
  OBJS-$(CONFIG_XSUB_ENCODER)            += xsubenc.o
+ OBJS-$(CONFIG_XWD_DECODER)             += xwddec.o
+ OBJS-$(CONFIG_XWD_ENCODER)             += xwdenc.o
 +OBJS-$(CONFIG_Y41P_DECODER)            += y41pdec.o
 +OBJS-$(CONFIG_Y41P_ENCODER)            += y41penc.o
  OBJS-$(CONFIG_YOP_DECODER)             += yop.o
 +OBJS-$(CONFIG_YUV4_DECODER)            += yuv4dec.o
 +OBJS-$(CONFIG_YUV4_ENCODER)            += yuv4enc.o
  OBJS-$(CONFIG_ZLIB_DECODER)            += lcldec.o
  OBJS-$(CONFIG_ZLIB_ENCODER)            += lclenc.o
  OBJS-$(CONFIG_ZMBV_DECODER)            += zmbv.o
Simple merge
@@@ -666,6 -664,102 +664,102 @@@ static av_cold int aac_encode_end(AVCod
      return 0;
  }
  
 -    s->coder = &ff_aac_coders[2];
+ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s)
+ {
+     int ret = 0;
+     dsputil_init(&s->dsp, avctx);
+     // window init
+     ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
+     ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
+     ff_init_ff_sine_windows(10);
+     ff_init_ff_sine_windows(7);
+     if (ret = ff_mdct_init(&s->mdct1024, 11, 0, 32768.0))
+         return ret;
+     if (ret = ff_mdct_init(&s->mdct128,   8, 0, 32768.0))
+         return ret;
+     return 0;
+ }
+ static av_cold int alloc_buffers(AVCodecContext *avctx, AACEncContext *s)
+ {
+     FF_ALLOCZ_OR_GOTO(avctx, s->buffer.samples, 3 * 1024 * s->channels * sizeof(s->buffer.samples[0]), alloc_fail);
+     FF_ALLOCZ_OR_GOTO(avctx, s->cpe, sizeof(ChannelElement) * s->chan_map[0], alloc_fail);
+     FF_ALLOCZ_OR_GOTO(avctx, avctx->extradata, 5 + FF_INPUT_BUFFER_PADDING_SIZE, alloc_fail);
+     for(int ch = 0; ch < s->channels; ch++)
+         s->planar_samples[ch] = s->buffer.samples + 3 * 1024 * ch;
+     return 0;
+ alloc_fail:
+     return AVERROR(ENOMEM);
+ }
+ static av_cold int aac_encode_init(AVCodecContext *avctx)
+ {
+     AACEncContext *s = avctx->priv_data;
+     int i, ret = 0;
+     const uint8_t *sizes[2];
+     uint8_t grouping[AAC_MAX_CHANNELS];
+     int lengths[2];
+     avctx->frame_size = 1024;
+     for (i = 0; i < 16; i++)
+         if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i])
+             break;
+     s->channels = avctx->channels;
+     ERROR_IF(i == 16,
+              "Unsupported sample rate %d\n", avctx->sample_rate);
+     ERROR_IF(s->channels > AAC_MAX_CHANNELS,
+              "Unsupported number of channels: %d\n", s->channels);
+     ERROR_IF(avctx->profile != FF_PROFILE_UNKNOWN && avctx->profile != FF_PROFILE_AAC_LOW,
+              "Unsupported profile %d\n", avctx->profile);
+     ERROR_IF(1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * s->channels,
+              "Too many bits per frame requested\n");
+     s->samplerate_index = i;
+     s->chan_map = aac_chan_configs[s->channels-1];
+     if (ret = dsp_init(avctx, s))
+         goto fail;
+     if (ret = alloc_buffers(avctx, s))
+         goto fail;
+     avctx->extradata_size = 5;
+     put_audio_specific_config(avctx);
+     sizes[0]   = swb_size_1024[i];
+     sizes[1]   = swb_size_128[i];
+     lengths[0] = ff_aac_num_swb_1024[i];
+     lengths[1] = ff_aac_num_swb_128[i];
+     for (i = 0; i < s->chan_map[0]; i++)
+         grouping[i] = s->chan_map[i + 1] == TYPE_CPE;
+     if (ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping))
+         goto fail;
+     s->psypp = ff_psy_preprocess_init(avctx);
++    s->coder = &ff_aac_coders[s->options.aac_coder];
+     s->lambda = avctx->global_quality ? avctx->global_quality : 120;
+     ff_aac_tableinit();
+     for (i = 0; i < 428; i++)
+         ff_aac_pow34sf_tab[i] = sqrt(ff_aac_pow2sf_tab[i] * sqrt(ff_aac_pow2sf_tab[i]));
+     return 0;
+ fail:
+     aac_encode_end(avctx);
+     return ret;
+ }
  #define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
  static const AVOption aacenc_options[] = {
      {"stereo_mode", "Stereo coding method", offsetof(AACEncContext, options.stereo_mode), AV_OPT_TYPE_INT, {.dbl = 0}, -1, 1, AACENC_FLAGS, "stereo_mode"},
Simple merge
Simple merge
@@@ -245,9 -230,8 +245,10 @@@ void avcodec_register_all(void
      REGISTER_DECODER (XAN_WC3, xan_wc3);
      REGISTER_DECODER (XAN_WC4, xan_wc4);
      REGISTER_DECODER (XL, xl);
+     REGISTER_ENCDEC  (XWD, xwd);
 +    REGISTER_ENCDEC  (Y41P, y41p);
      REGISTER_DECODER (YOP, yop);
 +    REGISTER_ENCDEC  (YUV4, yuv4);
      REGISTER_ENCDEC  (ZLIB, zlib);
      REGISTER_ENCDEC  (ZMBV, zmbv);
  
@@@ -255,14 -254,7 +255,15 @@@ enum CodecID 
      CODEC_ID_VBLE,
      CODEC_ID_DXTORY,
      CODEC_ID_V410,
+     CODEC_ID_XWD,
 +    CODEC_ID_Y41P       = MKBETAG('Y','4','1','P'),
 +    CODEC_ID_UTVIDEO = 0x800,
 +    CODEC_ID_ESCAPE130  = MKBETAG('E','1','3','0'),
 +    CODEC_ID_AVRP       = MKBETAG('A','V','R','P'),
 +
 +    CODEC_ID_G2M        = MKBETAG( 0 ,'G','2','M'),
 +    CODEC_ID_V308       = MKBETAG('V','3','0','8'),
 +    CODEC_ID_YUV4       = MKBETAG('Y','U','V','4'),
  
      /* various PCM "codecs" */
      CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
Simple merge
Simple merge
Simple merge
@@@ -21,8 -21,8 +21,8 @@@
  #define AVCODEC_VERSION_H
  
  #define LIBAVCODEC_VERSION_MAJOR 53
- #define LIBAVCODEC_VERSION_MINOR 57
- #define LIBAVCODEC_VERSION_MICRO 105
 -#define LIBAVCODEC_VERSION_MINOR 35
 -#define LIBAVCODEC_VERSION_MICRO  0
++#define LIBAVCODEC_VERSION_MINOR 58
++#define LIBAVCODEC_VERSION_MICRO 100
  
  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                 LIBAVCODEC_VERSION_MINOR, \
@@@ -326,14 -308,12 +326,14 @@@ OBJS-$(CONFIG_WC3_DEMUXER
  OBJS-$(CONFIG_WEBM_MUXER)                += matroskaenc.o matroska.o \
                                              riff.o isom.o avc.o \
                                              flacenc_header.o avlanguage.o
- OBJS-$(CONFIG_WSAUD_DEMUXER)             += westwood.o
- OBJS-$(CONFIG_WSVQA_DEMUXER)             += westwood.o
+ OBJS-$(CONFIG_WSAUD_DEMUXER)             += westwood_aud.o
+ OBJS-$(CONFIG_WSVQA_DEMUXER)             += westwood_vqa.o
 -OBJS-$(CONFIG_WTV_DEMUXER)               += wtv.o asfdec.o asf.o asfcrypt.o \
 +OBJS-$(CONFIG_WTV_DEMUXER)               += wtvdec.o wtv.o asfdec.o asf.o asfcrypt.o \
                                              avlanguage.o mpegts.o isom.o riff.o
 +OBJS-$(CONFIG_WTV_MUXER)                 += wtvenc.o wtv.o asf.o asfenc.o riff.o
  OBJS-$(CONFIG_WV_DEMUXER)                += wv.o apetag.o
  OBJS-$(CONFIG_XA_DEMUXER)                += xa.o
 +OBJS-$(CONFIG_XBIN_DEMUXER)              += bintext.o sauce.o
  OBJS-$(CONFIG_XMV_DEMUXER)               += xmv.o riff.o
  OBJS-$(CONFIG_XWMA_DEMUXER)              += xwma.o riff.o
  OBJS-$(CONFIG_YOP_DEMUXER)               += yop.o
@@@ -527,8 -501,8 +528,8 @@@ static const AVClass img2mux_class = 
  AVOutputFormat ff_image2_muxer = {
      .name           = "image2",
      .long_name      = NULL_IF_CONFIG_SMALL("image2 sequence"),
 -    .extensions     = "bmp,dpx,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
 -                      "ppm,sgi,tga,tif,tiff,jp2,xwd",
 +    .extensions     = "bmp,dpx,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
-                       "ppm,sgi,tga,tif,tiff,jp2,j2c",
++                      "ppm,sgi,tga,tif,tiff,jp2,j2c,xwd",
      .priv_data_size = sizeof(VideoData),
      .video_codec    = CODEC_ID_MJPEG,
      .write_header   = write_header,
index 0000000,2eff4cc..4a85147
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,251 +1,246 @@@
 - * This file is part of Libav.
+ /*
+  * Westwood Studios VQA Format Demuxer
+  * Copyright (c) 2003 The ffmpeg Project
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -        if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) {
 -            av_free(st->codec->extradata);
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ /**
+  * @file
+  * Westwood Studios VQA file demuxer
+  * by Mike Melanson (melanson@pcisys.net)
+  * for more information on the Westwood file formats, visit:
+  *   http://www.pcisys.net/~melanson/codecs/
+  *   http://www.geocities.com/SiliconValley/8682/aud3.txt
+  */
+ #include "libavutil/intreadwrite.h"
+ #include "avformat.h"
+ #include "internal.h"
+ #define FORM_TAG MKBETAG('F', 'O', 'R', 'M')
+ #define WVQA_TAG MKBETAG('W', 'V', 'Q', 'A')
+ #define VQHD_TAG MKBETAG('V', 'Q', 'H', 'D')
+ #define FINF_TAG MKBETAG('F', 'I', 'N', 'F')
+ #define SND0_TAG MKBETAG('S', 'N', 'D', '0')
+ #define SND1_TAG MKBETAG('S', 'N', 'D', '1')
+ #define SND2_TAG MKBETAG('S', 'N', 'D', '2')
+ #define VQFR_TAG MKBETAG('V', 'Q', 'F', 'R')
+ /* don't know what these tags are for, but acknowledge their existence */
+ #define CINF_TAG MKBETAG('C', 'I', 'N', 'F')
+ #define CINH_TAG MKBETAG('C', 'I', 'N', 'H')
+ #define CIND_TAG MKBETAG('C', 'I', 'N', 'D')
+ #define PINF_TAG MKBETAG('P', 'I', 'N', 'F')
+ #define PINH_TAG MKBETAG('P', 'I', 'N', 'H')
+ #define PIND_TAG MKBETAG('P', 'I', 'N', 'D')
+ #define CMDS_TAG MKBETAG('C', 'M', 'D', 'S')
+ #define VQA_HEADER_SIZE 0x2A
+ #define VQA_FRAMERATE 15
+ #define VQA_PREAMBLE_SIZE 8
+ typedef struct WsVqaDemuxContext {
+     int audio_samplerate;
+     int audio_channels;
+     int audio_bits;
+     int audio_stream_index;
+     int video_stream_index;
+     int64_t audio_frame_counter;
+ } WsVqaDemuxContext;
+ static int wsvqa_probe(AVProbeData *p)
+ {
+     /* need 12 bytes to qualify */
+     if (p->buf_size < 12)
+         return 0;
+     /* check for the VQA signatures */
+     if ((AV_RB32(&p->buf[0]) != FORM_TAG) ||
+         (AV_RB32(&p->buf[8]) != WVQA_TAG))
+         return 0;
+     return AVPROBE_SCORE_MAX;
+ }
+ static int wsvqa_read_header(AVFormatContext *s,
+                              AVFormatParameters *ap)
+ {
+     WsVqaDemuxContext *wsvqa = s->priv_data;
+     AVIOContext *pb = s->pb;
+     AVStream *st;
+     unsigned char *header;
+     unsigned char scratch[VQA_PREAMBLE_SIZE];
+     unsigned int chunk_tag;
+     unsigned int chunk_size;
+     /* initialize the video decoder stream */
+     st = avformat_new_stream(s, NULL);
+     if (!st)
+         return AVERROR(ENOMEM);
+     avpriv_set_pts_info(st, 33, 1, VQA_FRAMERATE);
+     wsvqa->video_stream_index = st->index;
+     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+     st->codec->codec_id = CODEC_ID_WS_VQA;
+     st->codec->codec_tag = 0;  /* no fourcc */
+     /* skip to the start of the VQA header */
+     avio_seek(pb, 20, SEEK_SET);
+     /* the VQA header needs to go to the decoder */
+     st->codec->extradata_size = VQA_HEADER_SIZE;
+     st->codec->extradata = av_mallocz(VQA_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+     header = (unsigned char *)st->codec->extradata;
+     if (avio_read(pb, st->codec->extradata, VQA_HEADER_SIZE) !=
+         VQA_HEADER_SIZE) {
+         av_free(st->codec->extradata);
+         return AVERROR(EIO);
+     }
+     st->codec->width = AV_RL16(&header[6]);
+     st->codec->height = AV_RL16(&header[8]);
+     /* initialize the audio decoder stream for VQA v1 or nonzero samplerate */
+     if (AV_RL16(&header[24]) || (AV_RL16(&header[0]) == 1 && AV_RL16(&header[2]) == 1)) {
+         st = avformat_new_stream(s, NULL);
+         if (!st)
+             return AVERROR(ENOMEM);
+         avpriv_set_pts_info(st, 33, 1, VQA_FRAMERATE);
+         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+         if (AV_RL16(&header[0]) == 1)
+             st->codec->codec_id = CODEC_ID_WESTWOOD_SND1;
+         else
+             st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS;
+         st->codec->codec_tag = 0;  /* no tag */
+         st->codec->sample_rate = AV_RL16(&header[24]);
+         if (!st->codec->sample_rate)
+             st->codec->sample_rate = 22050;
+         st->codec->channels = header[26];
+         if (!st->codec->channels)
+             st->codec->channels = 1;
+         st->codec->bits_per_coded_sample = 16;
+         st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
+             st->codec->bits_per_coded_sample / 4;
+         st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
+         wsvqa->audio_stream_index = st->index;
+         wsvqa->audio_samplerate = st->codec->sample_rate;
+         wsvqa->audio_channels = st->codec->channels;
+         wsvqa->audio_frame_counter = 0;
+     }
+     /* there are 0 or more chunks before the FINF chunk; iterate until
+      * FINF has been skipped and the file will be ready to be demuxed */
+     do {
 -        }
++        if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE)
+             return AVERROR(EIO);
 -            if (av_new_packet(pkt, chunk_size))
 -                return AVERROR(EIO);
 -            ret = avio_read(pb, pkt->data, chunk_size);
 -            if (ret != chunk_size) {
 -                av_free_packet(pkt);
+         chunk_tag = AV_RB32(&scratch[0]);
+         chunk_size = AV_RB32(&scratch[4]);
+         /* catch any unknown header tags, for curiousity */
+         switch (chunk_tag) {
+         case CINF_TAG:
+         case CINH_TAG:
+         case CIND_TAG:
+         case PINF_TAG:
+         case PINH_TAG:
+         case PIND_TAG:
+         case FINF_TAG:
+         case CMDS_TAG:
+             break;
+         default:
+             av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n",
+                 scratch[0], scratch[1],
+                 scratch[2], scratch[3]);
+             break;
+         }
+         avio_skip(pb, chunk_size);
+     } while (chunk_tag != FINF_TAG);
+     return 0;
+ }
+ static int wsvqa_read_packet(AVFormatContext *s,
+                              AVPacket *pkt)
+ {
+     WsVqaDemuxContext *wsvqa = s->priv_data;
+     AVIOContext *pb = s->pb;
+     int ret = -1;
+     unsigned char preamble[VQA_PREAMBLE_SIZE];
+     unsigned int chunk_type;
+     unsigned int chunk_size;
+     int skip_byte;
+     while (avio_read(pb, preamble, VQA_PREAMBLE_SIZE) == VQA_PREAMBLE_SIZE) {
+         chunk_type = AV_RB32(&preamble[0]);
+         chunk_size = AV_RB32(&preamble[4]);
++
+         skip_byte = chunk_size & 0x01;
+         if ((chunk_type == SND2_TAG || chunk_type == SND1_TAG) && wsvqa->audio_channels == 0) {
+             av_log(s, AV_LOG_ERROR, "audio chunk without any audio header information found\n");
+             return AVERROR_INVALIDDATA;
+         }
+         if ((chunk_type == SND1_TAG) || (chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) {
 -            }
++            ret= av_get_packet(pb, pkt, chunk_size);
++            if (ret<0)
+                 return AVERROR(EIO);
+             if (chunk_type == SND2_TAG) {
+                 pkt->stream_index = wsvqa->audio_stream_index;
+                 /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
+                 wsvqa->audio_frame_counter += (chunk_size * 2) / wsvqa->audio_channels;
+             } else if(chunk_type == SND1_TAG) {
+                 pkt->stream_index = wsvqa->audio_stream_index;
+                 /* unpacked size is stored in header */
+                 wsvqa->audio_frame_counter += AV_RL16(pkt->data) / wsvqa->audio_channels;
+             } else {
+                 pkt->stream_index = wsvqa->video_stream_index;
+             }
+             /* stay on 16-bit alignment */
+             if (skip_byte)
+                 avio_skip(pb, 1);
+             return ret;
+         } else {
+             switch(chunk_type){
+             case CMDS_TAG:
+             case SND0_TAG:
+                 break;
+             default:
+                 av_log(s, AV_LOG_INFO, "Skipping unknown chunk 0x%08X\n", chunk_type);
+             }
+             avio_skip(pb, chunk_size + skip_byte);
+         }
+     }
+     return ret;
+ }
+ AVInputFormat ff_wsvqa_demuxer = {
+     .name           = "wsvqa",
+     .long_name      = NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"),
+     .priv_data_size = sizeof(WsVqaDemuxContext),
+     .read_probe     = wsvqa_probe,
+     .read_header    = wsvqa_read_header,
+     .read_packet    = wsvqa_read_packet,
+ };