Merge remote branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 24 Apr 2011 01:38:03 +0000 (03:38 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 24 Apr 2011 01:41:22 +0000 (03:41 +0200)
* qatar/master:
  Handle unicode file names on windows
  rtp: Rename the open/close functions to alloc/free
  Lowercase all ff* program names.
  Refer to ff* tools by their lowercase names.
NOT Pulled  Replace more FFmpeg instances by Libav or ffmpeg.
  Replace `` by $() syntax in shell scripts.
  patcheck: Allow overiding grep program(s) through environment variables.
NOT Pulled  Remove stray libavcore and _g binary references.
  vorbis: Rename decoder/encoder files to follow general file naming scheme.
  aacenc: Fix whitespace after last commit.
  cook: Fix small typo in av_log_ask_for_sample message.
  aacenc: Finish 3GPP psymodel analysis for non mid/side cases.
  Remove RDFT dependency from AAC decoder.
  Add some debug log messages to AAC extradata
  Fix mov debug (u)int64_t format strings.
  bswap: use native types for av_bwap16().
  doc: FLV muxing is supported.
  applehttp: Handle AES-128 encrypted streams
  Add a protocol handler for AES CBC decryption with PKCS7 padding
  doc: Mention that DragonFly BSD requires __BSD_VISIBLE set

Conflicts:
ffplay.c
ffprobe.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
43 files changed:
1  2 
cmdutils.c
configure
doc/faq.texi
doc/ffmpeg.texi
doc/ffplay.texi
doc/ffprobe.texi
doc/ffserver.texi
doc/general.texi
ffmpeg.c
ffplay.c
ffprobe.c
ffserver.c
libavcodec/Makefile
libavcodec/aacdec.c
libavcodec/aacenc.c
libavcodec/aacpsy.c
libavcodec/cook.c
libavcodec/twinvq.c
libavcodec/vorbisdec.c
libavcodec/vorbisenc.c
libavformat/Makefile
libavformat/allformats.c
libavformat/applehttp.c
libavformat/mov.c
libavformat/os_support.c
libavformat/os_support.h
libavformat/rdt.c
libavformat/rtpdec.h
libavformat/rtpdec_amr.c
libavformat/rtpdec_asf.c
libavformat/rtpdec_h264.c
libavformat/rtpdec_latm.c
libavformat/rtpdec_mpeg4.c
libavformat/rtpdec_qcelp.c
libavformat/rtpdec_qdm2.c
libavformat/rtpdec_qt.c
libavformat/rtpdec_svq3.c
libavformat/rtpdec_vp8.c
libavformat/rtpdec_xiph.c
libavformat/rtsp.c
libavformat/version.h
libavutil/x86/bswap.h
tools/patcheck

diff --cc cmdutils.c
Simple merge
diff --cc configure
Simple merge
diff --cc doc/faq.texi
Simple merge
diff --cc doc/ffmpeg.texi
@@@ -1057,10 -1046,10 +1055,10 @@@ file to which you want to add them
  @ignore
  
  @setfilename ffmpeg
- @settitle FFmpeg video converter
+ @settitle ffmpeg video converter
  
  @c man begin SEEALSO
 -ffplay(1), ffprobe(1), ffserver(1) and the Libav HTML documentation
 +ffplay(1), ffprobe(1), ffserver(1) and the FFmpeg HTML documentation
  @c man end
  
  @c man begin AUTHORS
diff --cc doc/ffplay.texi
Simple merge
@@@ -119,10 -119,10 +119,10 @@@ with name "STREAM"
  @ignore
  
  @setfilename ffprobe
- @settitle FFprobe media prober
+ @settitle ffprobe media prober
  
  @c man begin SEEALSO
 -ffmpeg(1), ffplay(1), ffserver(1) and the Libav HTML documentation
 +ffmpeg(1), ffplay(1), ffserver(1) and the FFmpeg HTML documentation
  @c man end
  
  @c man begin AUTHORS
Simple merge
@@@ -786,12 -781,12 +786,12 @@@ to configure
  
  @subsection BSD
  
 -BSD make will not build Libav, you need to install and use GNU Make
 +BSD make will not build FFmpeg, you need to install and use GNU Make
  (@file{gmake}).
  
- @subsubsection FreeBSD
+ @subsubsection FreeBSD, DragonFly BSD
  
FreeBSD will not compile out-of-the-box due to broken system headers.
These systems will not compile out-of-the-box due to broken system headers.
  Passing @code{--extra-cflags=-D__BSD_VISIBLE} to configure will work
  around the problem. This may have unexpected sideeffects, so use it at
  your own risk. If you care about FreeBSD, please make an attempt at
diff --cc ffmpeg.c
+++ b/ffmpeg.c
@@@ -1,10 -1,10 +1,10 @@@
  /*
-  * FFmpeg main
+  * ffmpeg main
   * Copyright (c) 2000-2003 Fabrice Bellard
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * 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.
diff --cc ffplay.c
+++ b/ffplay.c
@@@ -1,10 -1,10 +1,10 @@@
  /*
-  * FFplay : Simple Media Player based on the FFmpeg libraries
 - * ffplay : Simple Media Player based on the Libav libraries
++ * ffplay : Simple Media Player based on the FFmpeg libraries
   * Copyright (c) 2003 Fabrice Bellard
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * 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.
diff --cc ffprobe.c
+++ b/ffprobe.c
@@@ -1,10 -1,10 +1,10 @@@
  /*
-  * FFprobe : Simple Media Prober based on the FFmpeg libraries
 - * ffprobe : Simple Media Prober based on the Libav libraries
++ * ffprobe : Simple Media Prober based on the FFmpeg libraries
   * Copyright (c) 2007-2010 Stefano Sabatini
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * 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.
diff --cc ffserver.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000,5fa7be1..5ed3631
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1668 +1,1679 @@@
 - * This file is part of Libav.
+ /**
+  * @file
+  * Vorbis I decoder
+  * @author Denes Balatoni  ( dbalatoni programozo hu )
+  *
 - * 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
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #undef V_DEBUG
+ //#define V_DEBUG
+ //#define AV_DEBUG(...) av_log(NULL, AV_LOG_INFO, __VA_ARGS__)
+ #include <math.h>
+ #define ALT_BITSTREAM_READER_LE
+ #include "avcodec.h"
+ #include "get_bits.h"
+ #include "dsputil.h"
+ #include "fft.h"
+ #include "fmtconvert.h"
+ #include "vorbis.h"
+ #include "xiph.h"
+ #define V_NB_BITS 8
+ #define V_NB_BITS2 11
+ #define V_MAX_VLCS (1 << 16)
+ #define V_MAX_PARTITIONS (1 << 20)
+ #ifndef V_DEBUG
+ #define AV_DEBUG(...)
+ #endif
+ #undef NDEBUG
+ #include <assert.h>
+ typedef struct {
+     uint_fast8_t dimensions;
+     uint_fast8_t lookup_type;
+     uint_fast8_t maxdepth;
+     VLC vlc;
+     float *codevectors;
+     unsigned int nb_bits;
+ } vorbis_codebook;
+ typedef union  vorbis_floor_u  vorbis_floor_data;
+ typedef struct vorbis_floor0_s vorbis_floor0;
+ typedef struct vorbis_floor1_s vorbis_floor1;
+ struct vorbis_context_s;
+ typedef
+ int (* vorbis_floor_decode_func)
+     (struct vorbis_context_s *, vorbis_floor_data *, float *);
+ typedef struct {
+     uint_fast8_t floor_type;
+     vorbis_floor_decode_func decode;
+     union vorbis_floor_u {
+         struct vorbis_floor0_s {
+             uint_fast8_t  order;
+             uint_fast16_t rate;
+             uint_fast16_t bark_map_size;
+             int_fast32_t *map[2];
+             uint_fast32_t map_size[2];
+             uint_fast8_t  amplitude_bits;
+             uint_fast8_t  amplitude_offset;
+             uint_fast8_t  num_books;
+             uint_fast8_t *book_list;
+             float        *lsp;
+         } t0;
+         struct vorbis_floor1_s {
+             uint_fast8_t partitions;
+             uint8_t      partition_class[32];
+             uint_fast8_t class_dimensions[16];
+             uint_fast8_t class_subclasses[16];
+             uint_fast8_t class_masterbook[16];
+             int_fast16_t subclass_books[16][8];
+             uint_fast8_t multiplier;
+             uint_fast16_t x_list_dim;
+             vorbis_floor1_entry *list;
+         } t1;
+     } data;
+ } vorbis_floor;
+ typedef struct {
+     uint_fast16_t type;
+     uint_fast32_t begin;
+     uint_fast32_t end;
+     unsigned      partition_size;
+     uint_fast8_t  classifications;
+     uint_fast8_t  classbook;
+     int_fast16_t  books[64][8];
+     uint_fast8_t  maxpass;
+     uint_fast16_t ptns_to_read;
+     uint8_t *classifs;
+ } vorbis_residue;
+ typedef struct {
+     uint_fast8_t  submaps;
+     uint_fast16_t coupling_steps;
+     uint_fast8_t *magnitude;
+     uint_fast8_t *angle;
+     uint_fast8_t *mux;
+     uint_fast8_t  submap_floor[16];
+     uint_fast8_t  submap_residue[16];
+ } vorbis_mapping;
+ typedef struct {
+     uint_fast8_t  blockflag;
+     uint_fast16_t windowtype;
+     uint_fast16_t transformtype;
+     uint_fast8_t  mapping;
+ } vorbis_mode;
+ typedef struct vorbis_context_s {
+     AVCodecContext *avccontext;
+     GetBitContext gb;
+     DSPContext dsp;
+     FmtConvertContext fmt_conv;
+     FFTContext mdct[2];
+     uint_fast8_t  first_frame;
+     uint_fast32_t version;
+     uint_fast8_t  audio_channels;
+     uint_fast32_t audio_samplerate;
+     uint_fast32_t bitrate_maximum;
+     uint_fast32_t bitrate_nominal;
+     uint_fast32_t bitrate_minimum;
+     uint_fast32_t blocksize[2];
+     const float  *win[2];
+     uint_fast16_t codebook_count;
+     vorbis_codebook *codebooks;
+     uint_fast8_t  floor_count;
+     vorbis_floor *floors;
+     uint_fast8_t  residue_count;
+     vorbis_residue *residues;
+     uint_fast8_t  mapping_count;
+     vorbis_mapping *mappings;
+     uint_fast8_t  mode_count;
+     vorbis_mode  *modes;
+     uint_fast8_t  mode_number; // mode number for the current packet
+     uint_fast8_t  previous_window;
+     float        *channel_residues;
+     float        *channel_floors;
+     float        *saved;
+     float         scale_bias; // for float->int conversion
+ } vorbis_context;
+ /* Helper functions */
+ #define BARK(x) \
+     (13.1f * atan(0.00074f * (x)) + 2.24f * atan(1.85e-8f * (x) * (x)) + 1e-4f * (x))
+ static const char idx_err_str[] = "Index value %d out of range (0 - %d) for %s at %s:%i\n";
+ #define VALIDATE_INDEX(idx, limit) \
+     if (idx >= limit) {\
+         av_log(vc->avccontext, AV_LOG_ERROR,\
+                idx_err_str,\
+                (int)(idx), (int)(limit - 1), #idx, __FILE__, __LINE__);\
+         return -1;\
+     }
+ #define GET_VALIDATED_INDEX(idx, bits, limit) \
+     {\
+         idx = get_bits(gb, bits);\
+         VALIDATE_INDEX(idx, limit)\
+     }
+ static float vorbisfloat2float(uint_fast32_t val)
+ {
+     double mant = val & 0x1fffff;
+     long exp    = (val & 0x7fe00000L) >> 21;
+     if (val & 0x80000000)
+         mant = -mant;
+     return ldexp(mant, exp - 20 - 768);
+ }
+ // Free all allocated memory -----------------------------------------
+ static void vorbis_free(vorbis_context *vc)
+ {
+     int_fast16_t i;
+     av_freep(&vc->channel_residues);
+     av_freep(&vc->channel_floors);
+     av_freep(&vc->saved);
+     for (i = 0; i < vc->residue_count; i++)
+         av_free(vc->residues[i].classifs);
+     av_freep(&vc->residues);
+     av_freep(&vc->modes);
+     ff_mdct_end(&vc->mdct[0]);
+     ff_mdct_end(&vc->mdct[1]);
+     for (i = 0; i < vc->codebook_count; ++i) {
+         av_free(vc->codebooks[i].codevectors);
+         free_vlc(&vc->codebooks[i].vlc);
+     }
+     av_freep(&vc->codebooks);
+     for (i = 0; i < vc->floor_count; ++i) {
+         if (vc->floors[i].floor_type == 0) {
+             av_free(vc->floors[i].data.t0.map[0]);
+             av_free(vc->floors[i].data.t0.map[1]);
+             av_free(vc->floors[i].data.t0.book_list);
+             av_free(vc->floors[i].data.t0.lsp);
+         } else {
+             av_free(vc->floors[i].data.t1.list);
+         }
+     }
+     av_freep(&vc->floors);
+     for (i = 0; i < vc->mapping_count; ++i) {
+         av_free(vc->mappings[i].magnitude);
+         av_free(vc->mappings[i].angle);
+         av_free(vc->mappings[i].mux);
+     }
+     av_freep(&vc->mappings);
+ }
+ // Parse setup header -------------------------------------------------
+ // Process codebooks part
+ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
+ {
+     uint_fast16_t cb;
+     uint8_t  *tmp_vlc_bits;
+     uint32_t *tmp_vlc_codes;
+     GetBitContext *gb = &vc->gb;
+     uint_fast16_t *codebook_multiplicands;
+     vc->codebook_count = get_bits(gb, 8) + 1;
+     AV_DEBUG(" Codebooks: %d \n", vc->codebook_count);
+     vc->codebooks = av_mallocz(vc->codebook_count * sizeof(vorbis_codebook));
+     tmp_vlc_bits  = av_mallocz(V_MAX_VLCS * sizeof(uint8_t));
+     tmp_vlc_codes = av_mallocz(V_MAX_VLCS * sizeof(uint32_t));
+     codebook_multiplicands = av_malloc(V_MAX_VLCS * sizeof(*codebook_multiplicands));
+     for (cb = 0; cb < vc->codebook_count; ++cb) {
+         vorbis_codebook *codebook_setup = &vc->codebooks[cb];
+         uint_fast8_t ordered;
+         uint_fast32_t t, used_entries = 0;
+         uint_fast32_t entries;
+         AV_DEBUG(" %d. Codebook \n", cb);
+         if (get_bits(gb, 24) != 0x564342) {
+             av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook setup data corrupt. \n", cb);
+             goto error;
+         }
+         codebook_setup->dimensions=get_bits(gb, 16);
+         if (codebook_setup->dimensions > 16 || codebook_setup->dimensions == 0) {
+             av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook's dimension is invalid (%d). \n", cb, codebook_setup->dimensions);
+             goto error;
+         }
+         entries = get_bits(gb, 24);
+         if (entries > V_MAX_VLCS) {
+             av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook has too many entries (%"PRIdFAST32"). \n", cb, entries);
+             goto error;
+         }
+         ordered = get_bits1(gb);
+         AV_DEBUG(" codebook_dimensions %d, codebook_entries %d \n", codebook_setup->dimensions, entries);
+         if (!ordered) {
+             uint_fast16_t ce;
+             uint_fast8_t  flag;
+             uint_fast8_t  sparse = get_bits1(gb);
+             AV_DEBUG(" not ordered \n");
+             if (sparse) {
+                 AV_DEBUG(" sparse \n");
+                 used_entries = 0;
+                 for (ce = 0; ce < entries; ++ce) {
+                     flag = get_bits1(gb);
+                     if (flag) {
+                         tmp_vlc_bits[ce] = get_bits(gb, 5) + 1;
+                         ++used_entries;
+                     } else
+                         tmp_vlc_bits[ce] = 0;
+                 }
+             } else {
+                 AV_DEBUG(" not sparse \n");
+                 used_entries = entries;
+                 for (ce = 0; ce < entries; ++ce)
+                     tmp_vlc_bits[ce] = get_bits(gb, 5) + 1;
+             }
+         } else {
+             uint_fast16_t current_entry = 0;
+             uint_fast8_t current_length = get_bits(gb, 5)+1;
+             AV_DEBUG(" ordered, current length: %d \n", current_length);  //FIXME
+             used_entries = entries;
+             for (; current_entry < used_entries && current_length <= 32; ++current_length) {
+                 uint_fast16_t i, number;
+                 AV_DEBUG(" number bits: %d ", ilog(entries - current_entry));
+                 number = get_bits(gb, ilog(entries - current_entry));
+                 AV_DEBUG(" number: %d \n", number);
+                 for (i = current_entry; i < number+current_entry; ++i)
+                     if (i < used_entries)
+                         tmp_vlc_bits[i] = current_length;
+                 current_entry+=number;
+             }
+             if (current_entry>used_entries) {
+                 av_log(vc->avccontext, AV_LOG_ERROR, " More codelengths than codes in codebook. \n");
+                 goto error;
+             }
+         }
+         codebook_setup->lookup_type = get_bits(gb, 4);
+         AV_DEBUG(" lookup type: %d : %s \n", codebook_setup->lookup_type, codebook_setup->lookup_type ? "vq" : "no lookup");
+ // If the codebook is used for (inverse) VQ, calculate codevectors.
+         if (codebook_setup->lookup_type == 1) {
+             uint_fast16_t i, j, k;
+             uint_fast16_t codebook_lookup_values = ff_vorbis_nth_root(entries, codebook_setup->dimensions);
+             float codebook_minimum_value = vorbisfloat2float(get_bits_long(gb, 32));
+             float codebook_delta_value   = vorbisfloat2float(get_bits_long(gb, 32));
+             uint_fast8_t codebook_value_bits = get_bits(gb, 4)+1;
+             uint_fast8_t codebook_sequence_p = get_bits1(gb);
+             AV_DEBUG(" We expect %d numbers for building the codevectors. \n", codebook_lookup_values);
+             AV_DEBUG("  delta %f minmum %f \n", codebook_delta_value, codebook_minimum_value);
+             for (i = 0; i < codebook_lookup_values; ++i) {
+                 codebook_multiplicands[i] = get_bits(gb, codebook_value_bits);
+                 AV_DEBUG(" multiplicands*delta+minmum : %e \n", (float)codebook_multiplicands[i]*codebook_delta_value+codebook_minimum_value);
+                 AV_DEBUG(" multiplicand %d \n", codebook_multiplicands[i]);
+             }
+ // Weed out unused vlcs and build codevector vector
+             codebook_setup->codevectors = used_entries ? av_mallocz(used_entries*codebook_setup->dimensions * sizeof(float)) : NULL;
+             for (j = 0, i = 0; i < entries; ++i) {
+                 uint_fast8_t dim = codebook_setup->dimensions;
+                 if (tmp_vlc_bits[i]) {
+                     float last = 0.0;
+                     uint_fast32_t lookup_offset = i;
+ #ifdef V_DEBUG
+                     av_log(vc->avccontext, AV_LOG_INFO, "Lookup offset %d ,", i);
+ #endif
+                     for (k = 0; k < dim; ++k) {
+                         uint_fast32_t multiplicand_offset = lookup_offset % codebook_lookup_values;
+                         codebook_setup->codevectors[j * dim + k] = codebook_multiplicands[multiplicand_offset] * codebook_delta_value + codebook_minimum_value + last;
+                         if (codebook_sequence_p)
+                             last = codebook_setup->codevectors[j * dim + k];
+                         lookup_offset/=codebook_lookup_values;
+                     }
+                     tmp_vlc_bits[j] = tmp_vlc_bits[i];
+ #ifdef V_DEBUG
+                     av_log(vc->avccontext, AV_LOG_INFO, "real lookup offset %d, vector: ", j);
+                     for (k = 0; k < dim; ++k)
+                         av_log(vc->avccontext, AV_LOG_INFO, " %f ", codebook_setup->codevectors[j * dim + k]);
+                     av_log(vc->avccontext, AV_LOG_INFO, "\n");
+ #endif
+                     ++j;
+                 }
+             }
+             if (j != used_entries) {
+                 av_log(vc->avccontext, AV_LOG_ERROR, "Bug in codevector vector building code. \n");
+                 goto error;
+             }
+             entries = used_entries;
+         } else if (codebook_setup->lookup_type >= 2) {
+             av_log(vc->avccontext, AV_LOG_ERROR, "Codebook lookup type not supported. \n");
+             goto error;
+         }
+ // Initialize VLC table
+         if (ff_vorbis_len2vlc(tmp_vlc_bits, tmp_vlc_codes, entries)) {
+             av_log(vc->avccontext, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n");
+             goto error;
+         }
+         codebook_setup->maxdepth = 0;
+         for (t = 0; t < entries; ++t)
+             if (tmp_vlc_bits[t] >= codebook_setup->maxdepth)
+                 codebook_setup->maxdepth = tmp_vlc_bits[t];
+         if (codebook_setup->maxdepth > 3 * V_NB_BITS)
+             codebook_setup->nb_bits = V_NB_BITS2;
+         else
+             codebook_setup->nb_bits = V_NB_BITS;
+         codebook_setup->maxdepth = (codebook_setup->maxdepth+codebook_setup->nb_bits - 1) / codebook_setup->nb_bits;
+         if (init_vlc(&codebook_setup->vlc, codebook_setup->nb_bits, entries, tmp_vlc_bits, sizeof(*tmp_vlc_bits), sizeof(*tmp_vlc_bits), tmp_vlc_codes, sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes), INIT_VLC_LE)) {
+             av_log(vc->avccontext, AV_LOG_ERROR, " Error generating vlc tables. \n");
+             goto error;
+         }
+     }
+     av_free(tmp_vlc_bits);
+     av_free(tmp_vlc_codes);
+     av_free(codebook_multiplicands);
+     return 0;
+ // Error:
+ error:
+     av_free(tmp_vlc_bits);
+     av_free(tmp_vlc_codes);
+     av_free(codebook_multiplicands);
+     return -1;
+ }
+ // Process time domain transforms part (unused in Vorbis I)
+ static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc)
+ {
+     GetBitContext *gb = &vc->gb;
+     uint_fast8_t i;
+     uint_fast8_t vorbis_time_count = get_bits(gb, 6) + 1;
+     for (i = 0; i < vorbis_time_count; ++i) {
+         uint_fast16_t vorbis_tdtransform = get_bits(gb, 16);
+         AV_DEBUG(" Vorbis time domain transform %d: %d \n", vorbis_time_count, vorbis_tdtransform);
+         if (vorbis_tdtransform) {
+             av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n");
+             return -1;
+         }
+     }
+     return 0;
+ }
+ // Process floors part
+ static int vorbis_floor0_decode(vorbis_context *vc,
+                                 vorbis_floor_data *vfu, float *vec);
+ static void create_map(vorbis_context *vc, uint_fast8_t floor_number);
+ static int vorbis_floor1_decode(vorbis_context *vc,
+                                 vorbis_floor_data *vfu, float *vec);
+ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
+ {
+     GetBitContext *gb = &vc->gb;
+     int i,j,k;
+     vc->floor_count = get_bits(gb, 6) + 1;
+     vc->floors = av_mallocz(vc->floor_count * sizeof(vorbis_floor));
+     for (i = 0; i < vc->floor_count; ++i) {
+         vorbis_floor *floor_setup = &vc->floors[i];
+         floor_setup->floor_type = get_bits(gb, 16);
+         AV_DEBUG(" %d. floor type %d \n", i, floor_setup->floor_type);
+         if (floor_setup->floor_type == 1) {
+             int maximum_class = -1;
+             uint_fast8_t  rangebits;
+             uint_fast32_t rangemax;
+             uint_fast16_t floor1_values = 2;
+             floor_setup->decode = vorbis_floor1_decode;
+             floor_setup->data.t1.partitions = get_bits(gb, 5);
+             AV_DEBUG(" %d.floor: %d partitions \n", i, floor_setup->data.t1.partitions);
+             for (j = 0; j < floor_setup->data.t1.partitions; ++j) {
+                 floor_setup->data.t1.partition_class[j] = get_bits(gb, 4);
+                 if (floor_setup->data.t1.partition_class[j] > maximum_class)
+                     maximum_class = floor_setup->data.t1.partition_class[j];
+                 AV_DEBUG(" %d. floor %d partition class %d \n", i, j, floor_setup->data.t1.partition_class[j]);
+             }
+             AV_DEBUG(" maximum class %d \n", maximum_class);
+             for (j = 0; j <= maximum_class; ++j) {
+                 floor_setup->data.t1.class_dimensions[j] = get_bits(gb, 3) + 1;
+                 floor_setup->data.t1.class_subclasses[j] = get_bits(gb, 2);
+                 AV_DEBUG(" %d floor %d class dim: %d subclasses %d \n", i, j, floor_setup->data.t1.class_dimensions[j], floor_setup->data.t1.class_subclasses[j]);
+                 if (floor_setup->data.t1.class_subclasses[j]) {
+                     GET_VALIDATED_INDEX(floor_setup->data.t1.class_masterbook[j], 8, vc->codebook_count)
+                     AV_DEBUG("   masterbook: %d \n", floor_setup->data.t1.class_masterbook[j]);
+                 }
+                 for (k = 0; k < (1 << floor_setup->data.t1.class_subclasses[j]); ++k) {
+                     int16_t bits = get_bits(gb, 8) - 1;
+                     if (bits != -1)
+                         VALIDATE_INDEX(bits, vc->codebook_count)
+                     floor_setup->data.t1.subclass_books[j][k] = bits;
+                     AV_DEBUG("    book %d. : %d \n", k, floor_setup->data.t1.subclass_books[j][k]);
+                 }
+             }
+             floor_setup->data.t1.multiplier = get_bits(gb, 2) + 1;
+             floor_setup->data.t1.x_list_dim = 2;
+             for (j = 0; j < floor_setup->data.t1.partitions; ++j)
+                 floor_setup->data.t1.x_list_dim+=floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]];
+             floor_setup->data.t1.list = av_mallocz(floor_setup->data.t1.x_list_dim * sizeof(vorbis_floor1_entry));
+             rangebits = get_bits(gb, 4);
+             rangemax = (1 << rangebits);
+             if (rangemax > vc->blocksize[1] / 2) {
+                 av_log(vc->avccontext, AV_LOG_ERROR,
+                        "Floor value is too large for blocksize: %d (%d)\n",
+                        rangemax, vc->blocksize[1] / 2);
+                 return -1;
+             }
+             floor_setup->data.t1.list[0].x = 0;
+             floor_setup->data.t1.list[1].x = rangemax;
+             for (j = 0; j < floor_setup->data.t1.partitions; ++j) {
+                 for (k = 0; k < floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]]; ++k, ++floor1_values) {
+                     floor_setup->data.t1.list[floor1_values].x = get_bits(gb, rangebits);
+                     AV_DEBUG(" %d. floor1 Y coord. %d \n", floor1_values, floor_setup->data.t1.list[floor1_values].x);
+                 }
+             }
+ // Precalculate order of x coordinates - needed for decode
+             ff_vorbis_ready_floor1_list(floor_setup->data.t1.list, floor_setup->data.t1.x_list_dim);
+         } else if (floor_setup->floor_type == 0) {
+             uint_fast8_t max_codebook_dim = 0;
+             floor_setup->decode = vorbis_floor0_decode;
+             floor_setup->data.t0.order          = get_bits(gb,  8);
+             floor_setup->data.t0.rate           = get_bits(gb, 16);
+             floor_setup->data.t0.bark_map_size  = get_bits(gb, 16);
+             floor_setup->data.t0.amplitude_bits = get_bits(gb,  6);
+             /* zero would result in a div by zero later *
+              * 2^0 - 1 == 0                             */
+             if (floor_setup->data.t0.amplitude_bits == 0) {
+                 av_log(vc->avccontext, AV_LOG_ERROR,
+                        "Floor 0 amplitude bits is 0.\n");
+                 return -1;
+             }
+             floor_setup->data.t0.amplitude_offset = get_bits(gb, 8);
+             floor_setup->data.t0.num_books        = get_bits(gb, 4) + 1;
+             /* allocate mem for booklist */
+             floor_setup->data.t0.book_list =
+                 av_malloc(floor_setup->data.t0.num_books);
+             if (!floor_setup->data.t0.book_list)
+                 return -1;
+             /* read book indexes */
+             {
+                 int idx;
+                 uint_fast8_t book_idx;
+                 for (idx = 0; idx < floor_setup->data.t0.num_books; ++idx) {
+                     GET_VALIDATED_INDEX(book_idx, 8, vc->codebook_count)
+                     floor_setup->data.t0.book_list[idx] = book_idx;
+                     if (vc->codebooks[book_idx].dimensions > max_codebook_dim)
+                         max_codebook_dim = vc->codebooks[book_idx].dimensions;
+                 }
+             }
+             create_map(vc, i);
+             /* codebook dim is for padding if codebook dim doesn't *
+              * divide order+1 then we need to read more data       */
+             floor_setup->data.t0.lsp =
+                 av_malloc((floor_setup->data.t0.order+1 + max_codebook_dim)
+                           * sizeof(float));
+             if (!floor_setup->data.t0.lsp)
+                 return -1;
+ #ifdef V_DEBUG /* debug output parsed headers */
+             AV_DEBUG("floor0 order: %u\n", floor_setup->data.t0.order);
+             AV_DEBUG("floor0 rate: %u\n", floor_setup->data.t0.rate);
+             AV_DEBUG("floor0 bark map size: %u\n",
+                      floor_setup->data.t0.bark_map_size);
+             AV_DEBUG("floor0 amplitude bits: %u\n",
+                      floor_setup->data.t0.amplitude_bits);
+             AV_DEBUG("floor0 amplitude offset: %u\n",
+                      floor_setup->data.t0.amplitude_offset);
+             AV_DEBUG("floor0 number of books: %u\n",
+                      floor_setup->data.t0.num_books);
+             AV_DEBUG("floor0 book list pointer: %p\n",
+                      floor_setup->data.t0.book_list);
+             {
+                 int idx;
+                 for (idx = 0; idx < floor_setup->data.t0.num_books; ++idx) {
+                     AV_DEBUG("  Book %d: %u\n",
+                              idx+1,
+                              floor_setup->data.t0.book_list[idx]);
+                 }
+             }
+ #endif
+         } else {
+             av_log(vc->avccontext, AV_LOG_ERROR, "Invalid floor type!\n");
+             return -1;
+         }
+     }
+     return 0;
+ }
+ // Process residues part
+ static int vorbis_parse_setup_hdr_residues(vorbis_context *vc)
+ {
+     GetBitContext *gb = &vc->gb;
+     uint_fast8_t i, j, k;
+     vc->residue_count = get_bits(gb, 6)+1;
+     vc->residues      = av_mallocz(vc->residue_count * sizeof(vorbis_residue));
+     AV_DEBUG(" There are %d residues. \n", vc->residue_count);
+     for (i = 0; i < vc->residue_count; ++i) {
+         vorbis_residue *res_setup = &vc->residues[i];
+         uint_fast8_t cascade[64];
+         uint_fast8_t high_bits;
+         uint_fast8_t low_bits;
+         res_setup->type = get_bits(gb, 16);
+         AV_DEBUG(" %d. residue type %d \n", i, res_setup->type);
+         res_setup->begin          = get_bits(gb, 24);
+         res_setup->end            = get_bits(gb, 24);
+         res_setup->partition_size = get_bits(gb, 24) + 1;
+         /* Validations to prevent a buffer overflow later. */
+         if (res_setup->begin>res_setup->end ||
+             res_setup->end > vc->avccontext->channels * vc->blocksize[1] / 2 ||
+             (res_setup->end-res_setup->begin) / res_setup->partition_size > V_MAX_PARTITIONS) {
+             av_log(vc->avccontext, AV_LOG_ERROR, "partition out of bounds: type, begin, end, size, blocksize: %"PRIdFAST16", %"PRIdFAST32", %"PRIdFAST32", %u, %"PRIdFAST32"\n", res_setup->type, res_setup->begin, res_setup->end, res_setup->partition_size, vc->blocksize[1] / 2);
+             return -1;
+         }
+         res_setup->classifications = get_bits(gb, 6) + 1;
+         GET_VALIDATED_INDEX(res_setup->classbook, 8, vc->codebook_count)
+         res_setup->ptns_to_read =
+             (res_setup->end - res_setup->begin) / res_setup->partition_size;
+         res_setup->classifs = av_malloc(res_setup->ptns_to_read *
+                                         vc->audio_channels *
+                                         sizeof(*res_setup->classifs));
+         if (!res_setup->classifs)
+             return AVERROR(ENOMEM);
+         AV_DEBUG("    begin %d end %d part.size %d classif.s %d classbook %d \n", res_setup->begin, res_setup->end, res_setup->partition_size,
+           res_setup->classifications, res_setup->classbook);
+         for (j = 0; j < res_setup->classifications; ++j) {
+             high_bits = 0;
+             low_bits  = get_bits(gb, 3);
+             if (get_bits1(gb))
+                 high_bits = get_bits(gb, 5);
+             cascade[j] = (high_bits << 3) + low_bits;
+             AV_DEBUG("     %d class casscade depth: %d \n", j, ilog(cascade[j]));
+         }
+         res_setup->maxpass = 0;
+         for (j = 0; j < res_setup->classifications; ++j) {
+             for (k = 0; k < 8; ++k) {
+                 if (cascade[j]&(1 << k)) {
+                     GET_VALIDATED_INDEX(res_setup->books[j][k], 8, vc->codebook_count)
+                     AV_DEBUG("     %d class casscade depth %d book: %d \n", j, k, res_setup->books[j][k]);
+                     if (k>res_setup->maxpass)
+                         res_setup->maxpass = k;
+                 } else {
+                     res_setup->books[j][k] = -1;
+                 }
+             }
+         }
+     }
+     return 0;
+ }
+ // Process mappings part
+ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc)
+ {
+     GetBitContext *gb = &vc->gb;
+     uint_fast8_t i, j;
+     vc->mapping_count = get_bits(gb, 6)+1;
+     vc->mappings      = av_mallocz(vc->mapping_count * sizeof(vorbis_mapping));
+     AV_DEBUG(" There are %d mappings. \n", vc->mapping_count);
+     for (i = 0; i < vc->mapping_count; ++i) {
+         vorbis_mapping *mapping_setup = &vc->mappings[i];
+         if (get_bits(gb, 16)) {
+             av_log(vc->avccontext, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n");
+             return -1;
+         }
+         if (get_bits1(gb)) {
+             mapping_setup->submaps = get_bits(gb, 4) + 1;
+         } else {
+             mapping_setup->submaps = 1;
+         }
+         if (get_bits1(gb)) {
+             mapping_setup->coupling_steps = get_bits(gb, 8) + 1;
+             mapping_setup->magnitude      = av_mallocz(mapping_setup->coupling_steps * sizeof(uint_fast8_t));
+             mapping_setup->angle          = av_mallocz(mapping_setup->coupling_steps * sizeof(uint_fast8_t));
+             for (j = 0; j < mapping_setup->coupling_steps; ++j) {
+                 GET_VALIDATED_INDEX(mapping_setup->magnitude[j], ilog(vc->audio_channels - 1), vc->audio_channels)
+                 GET_VALIDATED_INDEX(mapping_setup->angle[j],     ilog(vc->audio_channels - 1), vc->audio_channels)
+             }
+         } else {
+             mapping_setup->coupling_steps = 0;
+         }
+         AV_DEBUG("   %d mapping coupling steps: %d \n", i, mapping_setup->coupling_steps);
+         if (get_bits(gb, 2)) {
+             av_log(vc->avccontext, AV_LOG_ERROR, "%d. mapping setup data invalid. \n", i);
+             return -1; // following spec.
+         }
+         if (mapping_setup->submaps>1) {
+             mapping_setup->mux = av_mallocz(vc->audio_channels * sizeof(uint_fast8_t));
+             for (j = 0; j < vc->audio_channels; ++j)
+                 mapping_setup->mux[j] = get_bits(gb, 4);
+         }
+         for (j = 0; j < mapping_setup->submaps; ++j) {
+             skip_bits(gb, 8); // FIXME check?
+             GET_VALIDATED_INDEX(mapping_setup->submap_floor[j],   8, vc->floor_count)
+             GET_VALIDATED_INDEX(mapping_setup->submap_residue[j], 8, vc->residue_count)
+             AV_DEBUG("   %d mapping %d submap : floor %d, residue %d \n", i, j, mapping_setup->submap_floor[j], mapping_setup->submap_residue[j]);
+         }
+     }
+     return 0;
+ }
+ // Process modes part
+ static void create_map(vorbis_context *vc, uint_fast8_t floor_number)
+ {
+     vorbis_floor *floors = vc->floors;
+     vorbis_floor0 *vf;
+     int idx;
+     int_fast8_t blockflag;
+     int_fast32_t *map;
+     int_fast32_t n; //TODO: could theoretically be smaller?
+     for (blockflag = 0; blockflag < 2; ++blockflag) {
+         n = vc->blocksize[blockflag] / 2;
+         floors[floor_number].data.t0.map[blockflag] =
+             av_malloc((n+1) * sizeof(int_fast32_t)); // n + sentinel
+         map =  floors[floor_number].data.t0.map[blockflag];
+         vf  = &floors[floor_number].data.t0;
+         for (idx = 0; idx < n; ++idx) {
+             map[idx] = floor(BARK((vf->rate * idx) / (2.0f * n)) *
+                              ((vf->bark_map_size) /
+                               BARK(vf->rate / 2.0f)));
+             if (vf->bark_map_size-1 < map[idx])
+                 map[idx] = vf->bark_map_size - 1;
+         }
+         map[n] = -1;
+         vf->map_size[blockflag] = n;
+     }
+ #ifdef V_DEBUG
+     for (idx = 0; idx <= n; ++idx) {
+         AV_DEBUG("floor0 map: map at pos %d is %d\n",
+                  idx, map[idx]);
+     }
+ #endif
+ }
+ static int vorbis_parse_setup_hdr_modes(vorbis_context *vc)
+ {
+     GetBitContext *gb = &vc->gb;
+     uint_fast8_t i;
+     vc->mode_count = get_bits(gb, 6) + 1;
+     vc->modes      = av_mallocz(vc->mode_count * sizeof(vorbis_mode));
+     AV_DEBUG(" There are %d modes.\n", vc->mode_count);
+     for (i = 0; i < vc->mode_count; ++i) {
+         vorbis_mode *mode_setup = &vc->modes[i];
+         mode_setup->blockflag     = get_bits1(gb);
+         mode_setup->windowtype    = get_bits(gb, 16); //FIXME check
+         mode_setup->transformtype = get_bits(gb, 16); //FIXME check
+         GET_VALIDATED_INDEX(mode_setup->mapping, 8, vc->mapping_count);
+         AV_DEBUG(" %d mode: blockflag %d, windowtype %d, transformtype %d, mapping %d \n", i, mode_setup->blockflag, mode_setup->windowtype, mode_setup->transformtype, mode_setup->mapping);
+     }
+     return 0;
+ }
+ // Process the whole setup header using the functions above
+ static int vorbis_parse_setup_hdr(vorbis_context *vc)
+ {
+     GetBitContext *gb = &vc->gb;
+     if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') ||
+         (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') ||
+         (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n");
+         return -1;
+     }
+     if (vorbis_parse_setup_hdr_codebooks(vc)) {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n");
+         return -2;
+     }
+     if (vorbis_parse_setup_hdr_tdtransforms(vc)) {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n");
+         return -3;
+     }
+     if (vorbis_parse_setup_hdr_floors(vc)) {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n");
+         return -4;
+     }
+     if (vorbis_parse_setup_hdr_residues(vc)) {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n");
+         return -5;
+     }
+     if (vorbis_parse_setup_hdr_mappings(vc)) {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n");
+         return -6;
+     }
+     if (vorbis_parse_setup_hdr_modes(vc)) {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n");
+         return -7;
+     }
+     if (!get_bits1(gb)) {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n");
+         return -8; // framing flag bit unset error
+     }
+     return 0;
+ }
+ // Process the identification header
+ static int vorbis_parse_id_hdr(vorbis_context *vc)
+ {
+     GetBitContext *gb = &vc->gb;
+     uint_fast8_t bl0, bl1;
+     if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') ||
+         (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') ||
+         (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n");
+         return -1;
+     }
+     vc->version        = get_bits_long(gb, 32);    //FIXME check 0
+     vc->audio_channels = get_bits(gb, 8);
+     if (vc->audio_channels <= 0) {
+         av_log(vc->avccontext, AV_LOG_ERROR, "Invalid number of channels\n");
+         return -1;
+     }
+     vc->audio_samplerate = get_bits_long(gb, 32);
+     if (vc->audio_samplerate <= 0) {
+         av_log(vc->avccontext, AV_LOG_ERROR, "Invalid samplerate\n");
+         return -1;
+     }
+     vc->bitrate_maximum = get_bits_long(gb, 32);
+     vc->bitrate_nominal = get_bits_long(gb, 32);
+     vc->bitrate_minimum = get_bits_long(gb, 32);
+     bl0 = get_bits(gb, 4);
+     bl1 = get_bits(gb, 4);
+     vc->blocksize[0] = (1 << bl0);
+     vc->blocksize[1] = (1 << bl1);
+     if (bl0 > 13 || bl0 < 6 || bl1 > 13 || bl1 < 6 || bl1 < bl0) {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n");
+         return -3;
+     }
+     // output format int16
+     if (vc->blocksize[1] / 2 * vc->audio_channels * 2 > AVCODEC_MAX_AUDIO_FRAME_SIZE) {
+         av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis channel count makes "
+                "output packets too large.\n");
+         return -4;
+     }
+     vc->win[0] = ff_vorbis_vwin[bl0 - 6];
+     vc->win[1] = ff_vorbis_vwin[bl1 - 6];
+     if ((get_bits1(gb)) == 0) {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n");
+         return -2;
+     }
+     vc->channel_residues =  av_malloc((vc->blocksize[1]  / 2) * vc->audio_channels * sizeof(float));
+     vc->channel_floors   =  av_malloc((vc->blocksize[1]  / 2) * vc->audio_channels * sizeof(float));
+     vc->saved            =  av_mallocz((vc->blocksize[1] / 4) * vc->audio_channels * sizeof(float));
+     vc->previous_window  = 0;
+     ff_mdct_init(&vc->mdct[0], bl0, 1, -vc->scale_bias);
+     ff_mdct_init(&vc->mdct[1], bl1, 1, -vc->scale_bias);
+     AV_DEBUG(" vorbis version %d \n audio_channels %d \n audio_samplerate %d \n bitrate_max %d \n bitrate_nom %d \n bitrate_min %d \n blk_0 %d blk_1 %d \n ",
+             vc->version, vc->audio_channels, vc->audio_samplerate, vc->bitrate_maximum, vc->bitrate_nominal, vc->bitrate_minimum, vc->blocksize[0], vc->blocksize[1]);
+ /*
+     BLK = vc->blocksize[0];
+     for (i = 0; i < BLK / 2; ++i) {
+         vc->win[0][i] = sin(0.5*3.14159265358*(sin(((float)i + 0.5) / (float)BLK*3.14159265358))*(sin(((float)i + 0.5) / (float)BLK*3.14159265358)));
+     }
+ */
+     return 0;
+ }
+ // Process the extradata using the functions above (identification header, setup header)
+ static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
+ {
+     vorbis_context *vc = avccontext->priv_data ;
+     uint8_t *headers   = avccontext->extradata;
+     int headers_len    = avccontext->extradata_size;
+     uint8_t *header_start[3];
+     int header_len[3];
+     GetBitContext *gb = &(vc->gb);
+     int hdr_type;
+     vc->avccontext = avccontext;
+     dsputil_init(&vc->dsp, avccontext);
+     ff_fmt_convert_init(&vc->fmt_conv, avccontext);
+     vc->scale_bias = 32768.0f;
+     if (!headers_len) {
+         av_log(avccontext, AV_LOG_ERROR, "Extradata missing.\n");
+         return -1;
+     }
+     if (ff_split_xiph_headers(headers, headers_len, 30, header_start, header_len) < 0) {
+         av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n");
+         return -1;
+     }
+     init_get_bits(gb, header_start[0], header_len[0]*8);
+     hdr_type = get_bits(gb, 8);
+     if (hdr_type != 1) {
+         av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n");
+         return -1;
+     }
+     if (vorbis_parse_id_hdr(vc)) {
+         av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n");
+         vorbis_free(vc);
+         return -1;
+     }
+     init_get_bits(gb, header_start[2], header_len[2]*8);
+     hdr_type = get_bits(gb, 8);
+     if (hdr_type != 5) {
+         av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n");
+         vorbis_free(vc);
+         return -1;
+     }
+     if (vorbis_parse_setup_hdr(vc)) {
+         av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n");
+         vorbis_free(vc);
+         return -1;
+     }
+     if (vc->audio_channels > 8)
+         avccontext->channel_layout = 0;
+     else
+         avccontext->channel_layout = ff_vorbis_channel_layouts[vc->audio_channels - 1];
+     avccontext->channels    = vc->audio_channels;
+     avccontext->sample_rate = vc->audio_samplerate;
+     avccontext->frame_size  = FFMIN(vc->blocksize[0], vc->blocksize[1]) >> 2;
++    /* ffdshow custom code */
++#if CONFIG_AUDIO_FLOAT
++    avccontext->sample_fmt  = AV_SAMPLE_FMT_FLT;
++#else
+     avccontext->sample_fmt  = AV_SAMPLE_FMT_S16;
++#endif
+     return 0 ;
+ }
+ // Decode audiopackets -------------------------------------------------
+ // Read and decode floor
+ static int vorbis_floor0_decode(vorbis_context *vc,
+                                 vorbis_floor_data *vfu, float *vec)
+ {
+     vorbis_floor0 *vf = &vfu->t0;
+     float *lsp = vf->lsp;
+     uint_fast32_t amplitude;
+     uint_fast32_t book_idx;
+     uint_fast8_t blockflag = vc->modes[vc->mode_number].blockflag;
+     amplitude = get_bits(&vc->gb, vf->amplitude_bits);
+     if (amplitude > 0) {
+         float last = 0;
+         uint_fast16_t lsp_len = 0;
+         uint_fast16_t idx;
+         vorbis_codebook codebook;
+         book_idx = get_bits(&vc->gb, ilog(vf->num_books));
+         if (book_idx >= vf->num_books) {
+             av_log(vc->avccontext, AV_LOG_ERROR,
+                     "floor0 dec: booknumber too high!\n");
+             book_idx =  0;
+         }
+         AV_DEBUG("floor0 dec: booknumber: %u\n", book_idx);
+         codebook = vc->codebooks[vf->book_list[book_idx]];
+         /* Invalid codebook! */
+         if (!codebook.codevectors)
+             return -1;
+         while (lsp_len<vf->order) {
+             int vec_off;
+             AV_DEBUG("floor0 dec: book dimension: %d\n", codebook.dimensions);
+             AV_DEBUG("floor0 dec: maximum depth: %d\n", codebook.maxdepth);
+             /* read temp vector */
+             vec_off = get_vlc2(&vc->gb, codebook.vlc.table,
+                                codebook.nb_bits, codebook.maxdepth)
+                       * codebook.dimensions;
+             AV_DEBUG("floor0 dec: vector offset: %d\n", vec_off);
+             /* copy each vector component and add last to it */
+             for (idx = 0; idx < codebook.dimensions; ++idx)
+                 lsp[lsp_len+idx] = codebook.codevectors[vec_off+idx] + last;
+             last = lsp[lsp_len+idx-1]; /* set last to last vector component */
+             lsp_len += codebook.dimensions;
+         }
+ #ifdef V_DEBUG
+         /* DEBUG: output lsp coeffs */
+         {
+             int idx;
+             for (idx = 0; idx < lsp_len; ++idx)
+                 AV_DEBUG("floor0 dec: coeff at %d is %f\n", idx, lsp[idx]);
+         }
+ #endif
+         /* synthesize floor output vector */
+         {
+             int i;
+             int order = vf->order;
+             float wstep = M_PI / vf->bark_map_size;
+             for (i = 0; i < order; i++)
+                 lsp[i] = 2.0f * cos(lsp[i]);
+             AV_DEBUG("floor0 synth: map_size = %d; m = %d; wstep = %f\n",
+                      vf->map_size, order, wstep);
+             i = 0;
+             while (i < vf->map_size[blockflag]) {
+                 int j, iter_cond = vf->map[blockflag][i];
+                 float p = 0.5f;
+                 float q = 0.5f;
+                 float two_cos_w = 2.0f * cos(wstep * iter_cond); // needed all times
+                 /* similar part for the q and p products */
+                 for (j = 0; j + 1 < order; j += 2) {
+                     q *= lsp[j]     - two_cos_w;
+                     p *= lsp[j + 1] - two_cos_w;
+                 }
+                 if (j == order) { // even order
+                     p *= p * (2.0f - two_cos_w);
+                     q *= q * (2.0f + two_cos_w);
+                 } else { // odd order
+                     q *= two_cos_w-lsp[j]; // one more time for q
+                     /* final step and square */
+                     p *= p * (4.f - two_cos_w * two_cos_w);
+                     q *= q;
+                 }
+                 /* calculate linear floor value */
+                 q = exp((((amplitude*vf->amplitude_offset) /
+                           (((1 << vf->amplitude_bits) - 1) * sqrt(p + q)))
+                          - vf->amplitude_offset) * .11512925f);
+                 /* fill vector */
+                 do {
+                     vec[i] = q; ++i;
+                 } while (vf->map[blockflag][i] == iter_cond);
+             }
+         }
+     } else {
+         /* this channel is unused */
+         return 1;
+     }
+     AV_DEBUG(" Floor0 decoded\n");
+     return 0;
+ }
+ static int vorbis_floor1_decode(vorbis_context *vc,
+                                 vorbis_floor_data *vfu, float *vec)
+ {
+     vorbis_floor1 *vf = &vfu->t1;
+     GetBitContext *gb = &vc->gb;
+     uint_fast16_t range_v[4] = { 256, 128, 86, 64 };
+     uint_fast16_t range = range_v[vf->multiplier-1];
+     uint_fast16_t floor1_Y[258];
+     uint_fast16_t floor1_Y_final[258];
+     int floor1_flag[258];
+     uint_fast8_t class_;
+     uint_fast8_t cdim;
+     uint_fast8_t cbits;
+     uint_fast8_t csub;
+     uint_fast8_t cval;
+     int_fast16_t book;
+     uint_fast16_t offset;
+     uint_fast16_t i,j;
+     int_fast16_t adx, ady, dy, off, predicted;
+     int_fast32_t err;
+     if (!get_bits1(gb)) // silence
+         return 1;
+ // Read values (or differences) for the floor's points
+     floor1_Y[0] = get_bits(gb, ilog(range - 1));
+     floor1_Y[1] = get_bits(gb, ilog(range - 1));
+     AV_DEBUG("floor 0 Y %d floor 1 Y %d \n", floor1_Y[0], floor1_Y[1]);
+     offset = 2;
+     for (i = 0; i < vf->partitions; ++i) {
+         class_ = vf->partition_class[i];
+         cdim   = vf->class_dimensions[class_];
+         cbits  = vf->class_subclasses[class_];
+         csub = (1 << cbits) - 1;
+         cval = 0;
+         AV_DEBUG("Cbits %d \n", cbits);
+         if (cbits) // this reads all subclasses for this partition's class
+             cval = get_vlc2(gb, vc->codebooks[vf->class_masterbook[class_]].vlc.table,
+                             vc->codebooks[vf->class_masterbook[class_]].nb_bits, 3);
+         for (j = 0; j < cdim; ++j) {
+             book = vf->subclass_books[class_][cval & csub];
+             AV_DEBUG("book %d Cbits %d cval %d  bits:%d \n", book, cbits, cval, get_bits_count(gb));
+             cval = cval >> cbits;
+             if (book > -1) {
+                 floor1_Y[offset+j] = get_vlc2(gb, vc->codebooks[book].vlc.table,
+                 vc->codebooks[book].nb_bits, 3);
+             } else {
+                 floor1_Y[offset+j] = 0;
+             }
+             AV_DEBUG(" floor(%d) = %d \n", vf->list[offset+j].x, floor1_Y[offset+j]);
+         }
+         offset+=cdim;
+     }
+ // Amplitude calculation from the differences
+     floor1_flag[0] = 1;
+     floor1_flag[1] = 1;
+     floor1_Y_final[0] = floor1_Y[0];
+     floor1_Y_final[1] = floor1_Y[1];
+     for (i = 2; i < vf->x_list_dim; ++i) {
+         uint_fast16_t val, highroom, lowroom, room;
+         uint_fast16_t high_neigh_offs;
+         uint_fast16_t low_neigh_offs;
+         low_neigh_offs  = vf->list[i].low;
+         high_neigh_offs = vf->list[i].high;
+         dy  = floor1_Y_final[high_neigh_offs] - floor1_Y_final[low_neigh_offs];  // render_point begin
+         adx = vf->list[high_neigh_offs].x - vf->list[low_neigh_offs].x;
+         ady = FFABS(dy);
+         err = ady * (vf->list[i].x - vf->list[low_neigh_offs].x);
+         off = err / adx;
+         if (dy < 0) {
+             predicted = floor1_Y_final[low_neigh_offs] - off;
+         } else {
+             predicted = floor1_Y_final[low_neigh_offs] + off;
+         } // render_point end
+         val = floor1_Y[i];
+         highroom = range-predicted;
+         lowroom  = predicted;
+         if (highroom < lowroom) {
+             room = highroom * 2;
+         } else {
+             room = lowroom * 2;   // SPEC mispelling
+         }
+         if (val) {
+             floor1_flag[low_neigh_offs]  = 1;
+             floor1_flag[high_neigh_offs] = 1;
+             floor1_flag[i]               = 1;
+             if (val >= room) {
+                 if (highroom > lowroom) {
+                     floor1_Y_final[i] = val - lowroom + predicted;
+                 } else {
+                     floor1_Y_final[i] = predicted - val + highroom - 1;
+                 }
+             } else {
+                 if (val & 1) {
+                     floor1_Y_final[i] = predicted - (val + 1) / 2;
+                 } else {
+                     floor1_Y_final[i] = predicted + val / 2;
+                 }
+             }
+         } else {
+             floor1_flag[i]    = 0;
+             floor1_Y_final[i] = predicted;
+         }
+         AV_DEBUG(" Decoded floor(%d) = %d / val %d \n", vf->list[i].x, floor1_Y_final[i], val);
+     }
+ // Curve synth - connect the calculated dots and convert from dB scale FIXME optimize ?
+     ff_vorbis_floor1_render_list(vf->list, vf->x_list_dim, floor1_Y_final, floor1_flag, vf->multiplier, vec, vf->list[1].x);
+     AV_DEBUG(" Floor decoded\n");
+     return 0;
+ }
+ // Read and decode residue
+ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc,
+                                                            vorbis_residue *vr,
+                                                            uint_fast8_t ch,
+                                                            uint_fast8_t *do_not_decode,
+                                                            float *vec,
+                                                            uint_fast16_t vlen,
+                                                            int vr_type)
+ {
+     GetBitContext *gb = &vc->gb;
+     uint_fast8_t c_p_c = vc->codebooks[vr->classbook].dimensions;
+     uint_fast16_t ptns_to_read = vr->ptns_to_read;
+     uint8_t *classifs = vr->classifs;
+     uint_fast8_t pass;
+     uint_fast8_t ch_used;
+     uint_fast8_t i,j,l;
+     uint_fast16_t k;
+     if (vr_type == 2) {
+         for (j = 1; j < ch; ++j)
+             do_not_decode[0] &= do_not_decode[j];  // FIXME - clobbering input
+         if (do_not_decode[0])
+             return 0;
+         ch_used = 1;
+     } else {
+         ch_used = ch;
+     }
+     AV_DEBUG(" residue type 0/1/2 decode begin, ch: %d  cpc %d  \n", ch, c_p_c);
+     for (pass = 0; pass <= vr->maxpass; ++pass) { // FIXME OPTIMIZE?
+         uint_fast16_t voffset;
+         uint_fast16_t partition_count;
+         uint_fast16_t j_times_ptns_to_read;
+         voffset = vr->begin;
+         for (partition_count = 0; partition_count < ptns_to_read;) {  // SPEC        error
+             if (!pass) {
+                 uint_fast32_t inverse_class = ff_inverse[vr->classifications];
+                 for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) {
+                     if (!do_not_decode[j]) {
+                         uint_fast32_t temp = get_vlc2(gb, vc->codebooks[vr->classbook].vlc.table,
+                         vc->codebooks[vr->classbook].nb_bits, 3);
+                         AV_DEBUG("Classword: %d \n", temp);
+                         assert(vr->classifications > 1 && temp <= 65536); //needed for inverse[]
+                         for (i = 0; i < c_p_c; ++i) {
+                             uint_fast32_t temp2;
+                             temp2 = (((uint_fast64_t)temp) * inverse_class) >> 32;
+                             if (partition_count + c_p_c - 1 - i < ptns_to_read)
+                                 classifs[j_times_ptns_to_read + partition_count + c_p_c - 1 - i] = temp - temp2 * vr->classifications;
+                             temp = temp2;
+                         }
+                     }
+                     j_times_ptns_to_read += ptns_to_read;
+                 }
+             }
+             for (i = 0; (i < c_p_c) && (partition_count < ptns_to_read); ++i) {
+                 for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) {
+                     uint_fast16_t voffs;
+                     if (!do_not_decode[j]) {
+                         uint_fast8_t vqclass = classifs[j_times_ptns_to_read+partition_count];
+                         int_fast16_t vqbook = vr->books[vqclass][pass];
+                         if (vqbook >= 0 && vc->codebooks[vqbook].codevectors) {
+                             uint_fast16_t coffs;
+                             unsigned dim =  vc->codebooks[vqbook].dimensions; // not uint_fast8_t: 64bit is slower here on amd64
+                             uint_fast16_t step = dim == 1 ? vr->partition_size
+                                                           : FASTDIV(vr->partition_size, dim);
+                             vorbis_codebook codebook = vc->codebooks[vqbook];
+                             if (vr_type == 0) {
+                                 voffs = voffset+j*vlen;
+                                 for (k = 0; k < step; ++k) {
+                                     coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim;
+                                     for (l = 0; l < dim; ++l)
+                                         vec[voffs + k + l * step] += codebook.codevectors[coffs + l];  // FPMATH
+                                 }
+                             } else if (vr_type == 1) {
+                                 voffs = voffset + j * vlen;
+                                 for (k = 0; k < step; ++k) {
+                                     coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim;
+                                     for (l = 0; l < dim; ++l, ++voffs) {
+                                         vec[voffs]+=codebook.codevectors[coffs+l];  // FPMATH
+                                         AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d  \n", pass, voffs, vec[voffs], codebook.codevectors[coffs+l], coffs);
+                                     }
+                                 }
+                             } else if (vr_type == 2 && ch == 2 && (voffset & 1) == 0 && (dim & 1) == 0) { // most frequent case optimized
+                                 voffs = voffset >> 1;
+                                 if (dim == 2) {
+                                     for (k = 0; k < step; ++k) {
+                                         coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * 2;
+                                         vec[voffs + k       ] += codebook.codevectors[coffs    ];  // FPMATH
+                                         vec[voffs + k + vlen] += codebook.codevectors[coffs + 1];  // FPMATH
+                                     }
+                                 } else if (dim == 4) {
+                                     for (k = 0; k < step; ++k, voffs += 2) {
+                                         coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * 4;
+                                         vec[voffs           ] += codebook.codevectors[coffs    ];  // FPMATH
+                                         vec[voffs + 1       ] += codebook.codevectors[coffs + 2];  // FPMATH
+                                         vec[voffs + vlen    ] += codebook.codevectors[coffs + 1];  // FPMATH
+                                         vec[voffs + vlen + 1] += codebook.codevectors[coffs + 3];  // FPMATH
+                                     }
+                                 } else
+                                 for (k = 0; k < step; ++k) {
+                                     coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim;
+                                     for (l = 0; l < dim; l += 2, voffs++) {
+                                         vec[voffs       ] += codebook.codevectors[coffs + l    ];  // FPMATH
+                                         vec[voffs + vlen] += codebook.codevectors[coffs + l + 1];  // FPMATH
+                                         AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d+%d  \n", pass, voffset / ch + (voffs % ch) * vlen, vec[voffset / ch + (voffs % ch) * vlen], codebook.codevectors[coffs + l], coffs, l);
+                                     }
+                                 }
+                             } else if (vr_type == 2) {
+                                 voffs = voffset;
+                                 for (k = 0; k < step; ++k) {
+                                     coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim;
+                                     for (l = 0; l < dim; ++l, ++voffs) {
+                                         vec[voffs / ch + (voffs % ch) * vlen] += codebook.codevectors[coffs + l];  // FPMATH FIXME use if and counter instead of / and %
+                                         AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d+%d  \n", pass, voffset / ch + (voffs % ch) * vlen, vec[voffset / ch + (voffs % ch) * vlen], codebook.codevectors[coffs + l], coffs, l);
+                                     }
+                                 }
+                             }
+                         }
+                     }
+                     j_times_ptns_to_read += ptns_to_read;
+                 }
+                 ++partition_count;
+                 voffset += vr->partition_size;
+             }
+         }
+     }
+     return 0;
+ }
+ static inline int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr,
+                                         uint_fast8_t ch,
+                                         uint_fast8_t *do_not_decode,
+                                         float *vec, uint_fast16_t vlen)
+ {
+     if (vr->type == 2)
+         return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 2);
+     else if (vr->type == 1)
+         return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 1);
+     else if (vr->type == 0)
+         return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 0);
+     else {
+         av_log(vc->avccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n");
+         return -1;
+     }
+ }
+ void vorbis_inverse_coupling(float *mag, float *ang, int blocksize)
+ {
+     int i;
+     for (i = 0;  i < blocksize;  i++) {
+         if (mag[i] > 0.0) {
+             if (ang[i] > 0.0) {
+                 ang[i] = mag[i] - ang[i];
+             } else {
+                 float temp = ang[i];
+                 ang[i]     = mag[i];
+                 mag[i]    += temp;
+             }
+         } else {
+             if (ang[i] > 0.0) {
+                 ang[i] += mag[i];
+             } else {
+                 float temp = ang[i];
+                 ang[i]     = mag[i];
+                 mag[i]    -= temp;
+             }
+         }
+     }
+ }
+ // Decode the audio packet using the functions above
+ static int vorbis_parse_audio_packet(vorbis_context *vc)
+ {
+     GetBitContext *gb = &vc->gb;
+     FFTContext *mdct;
+     uint_fast8_t previous_window = vc->previous_window;
+     uint_fast8_t mode_number;
+     uint_fast8_t blockflag;
+     uint_fast16_t blocksize;
+     int_fast32_t i,j;
+     uint_fast8_t no_residue[255];
+     uint_fast8_t do_not_decode[255];
+     vorbis_mapping *mapping;
+     float *ch_res_ptr   = vc->channel_residues;
+     float *ch_floor_ptr = vc->channel_floors;
+     uint_fast8_t res_chan[255];
+     uint_fast8_t res_num = 0;
+     int_fast16_t retlen  = 0;
+     if (get_bits1(gb)) {
+         av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n");
+         return -1; // packet type not audio
+     }
+     if (vc->mode_count == 1) {
+         mode_number = 0;
+     } else {
+         GET_VALIDATED_INDEX(mode_number, ilog(vc->mode_count-1), vc->mode_count)
+     }
+     vc->mode_number = mode_number;
+     mapping = &vc->mappings[vc->modes[mode_number].mapping];
+     AV_DEBUG(" Mode number: %d , mapping: %d , blocktype %d \n", mode_number, vc->modes[mode_number].mapping, vc->modes[mode_number].blockflag);
+     blockflag = vc->modes[mode_number].blockflag;
+     blocksize = vc->blocksize[blockflag];
+     if (blockflag)
+         skip_bits(gb, 2); // previous_window, next_window
+     memset(ch_res_ptr,   0, sizeof(float) * vc->audio_channels * blocksize / 2); //FIXME can this be removed ?
+     memset(ch_floor_ptr, 0, sizeof(float) * vc->audio_channels * blocksize / 2); //FIXME can this be removed ?
+ // Decode floor
+     for (i = 0; i < vc->audio_channels; ++i) {
+         vorbis_floor *floor;
+         int ret;
+         if (mapping->submaps > 1) {
+             floor = &vc->floors[mapping->submap_floor[mapping->mux[i]]];
+         } else {
+             floor = &vc->floors[mapping->submap_floor[0]];
+         }
+         ret = floor->decode(vc, &floor->data, ch_floor_ptr);
+         if (ret < 0) {
+             av_log(vc->avccontext, AV_LOG_ERROR, "Invalid codebook in vorbis_floor_decode.\n");
+             return -1;
+         }
+         no_residue[i] = ret;
+         ch_floor_ptr += blocksize / 2;
+     }
+ // Nonzero vector propagate
+     for (i = mapping->coupling_steps - 1; i >= 0; --i) {
+         if (!(no_residue[mapping->magnitude[i]] & no_residue[mapping->angle[i]])) {
+             no_residue[mapping->magnitude[i]] = 0;
+             no_residue[mapping->angle[i]]     = 0;
+         }
+     }
+ // Decode residue
+     for (i = 0; i < mapping->submaps; ++i) {
+         vorbis_residue *residue;
+         uint_fast8_t ch = 0;
+         for (j = 0; j < vc->audio_channels; ++j) {
+             if ((mapping->submaps == 1) || (i == mapping->mux[j])) {
+                 res_chan[j] = res_num;
+                 if (no_residue[j]) {
+                     do_not_decode[ch] = 1;
+                 } else {
+                     do_not_decode[ch] = 0;
+                 }
+                 ++ch;
+                 ++res_num;
+             }
+         }
+         residue = &vc->residues[mapping->submap_residue[i]];
+         vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, blocksize/2);
+         ch_res_ptr += ch * blocksize / 2;
+     }
+ // Inverse coupling
+     for (i = mapping->coupling_steps - 1; i >= 0; --i) { //warning: i has to be signed
+         float *mag, *ang;
+         mag = vc->channel_residues+res_chan[mapping->magnitude[i]] * blocksize / 2;
+         ang = vc->channel_residues+res_chan[mapping->angle[i]]     * blocksize / 2;
+         vc->dsp.vorbis_inverse_coupling(mag, ang, blocksize / 2);
+     }
+ // Dotproduct, MDCT
+     mdct = &vc->mdct[blockflag];
+     for (j = vc->audio_channels-1;j >= 0; j--) {
+         ch_floor_ptr = vc->channel_floors   + j           * blocksize / 2;
+         ch_res_ptr   = vc->channel_residues + res_chan[j] * blocksize / 2;
+         vc->dsp.vector_fmul(ch_floor_ptr, ch_floor_ptr, ch_res_ptr, blocksize / 2);
+         mdct->imdct_half(mdct, ch_res_ptr, ch_floor_ptr);
+     }
+ // Overlap/add, save data for next overlapping  FPMATH
+     retlen = (blocksize + vc->blocksize[previous_window]) / 4;
+     for (j = 0; j < vc->audio_channels; j++) {
+         uint_fast16_t bs0 = vc->blocksize[0];
+         uint_fast16_t bs1 = vc->blocksize[1];
+         float *residue    = vc->channel_residues + res_chan[j] * blocksize / 2;
+         float *saved      = vc->saved + j * bs1 / 4;
+         float *ret        = vc->channel_floors + j * retlen;
+         float *buf        = residue;
+         const float *win  = vc->win[blockflag & previous_window];
+         if (blockflag == previous_window) {
+             vc->dsp.vector_fmul_window(ret, saved, buf, win, blocksize / 4);
+         } else if (blockflag > previous_window) {
+             vc->dsp.vector_fmul_window(ret, saved, buf, win, bs0 / 4);
+             memcpy(ret+bs0/2, buf+bs0/4, ((bs1-bs0)/4) * sizeof(float));
+         } else {
+             memcpy(ret, saved, ((bs1 - bs0) / 4) * sizeof(float));
+             vc->dsp.vector_fmul_window(ret + (bs1 - bs0) / 4, saved + (bs1 - bs0) / 4, buf, win, bs0 / 4);
+         }
+         memcpy(saved, buf + blocksize / 4, blocksize / 4 * sizeof(float));
+     }
+     vc->previous_window = blockflag;
+     return retlen;
+ }
+ // Return the decoded audio packet through the standard api
+ static int vorbis_decode_frame(AVCodecContext *avccontext,
+                                void *data, int *data_size,
+                                AVPacket *avpkt)
+ {
+     const uint8_t *buf = avpkt->data;
+     int buf_size       = avpkt->size;
+     vorbis_context *vc = avccontext->priv_data ;
+     GetBitContext *gb = &(vc->gb);
+     const float *channel_ptrs[255];
+     int i;
+     int_fast16_t len;
+     if (!buf_size)
+         return 0;
+     AV_DEBUG("packet length %d \n", buf_size);
+     init_get_bits(gb, buf, buf_size*8);
+     len = vorbis_parse_audio_packet(vc);
+     if (len <= 0) {
+         *data_size = 0;
+         return buf_size;
+     }
+     if (!vc->first_frame) {
+         vc->first_frame = 1;
+         *data_size = 0;
+         return buf_size ;
+     }
+     AV_DEBUG("parsed %d bytes %d bits, returned %d samples (*ch*bits) \n", get_bits_count(gb)/8, get_bits_count(gb)%8, len);
+     if (vc->audio_channels > 8) {
+         for (i = 0; i < vc->audio_channels; i++)
+             channel_ptrs[i] = vc->channel_floors + i * len;
+     } else {
+         for (i = 0; i < vc->audio_channels; i++)
+             channel_ptrs[i] = vc->channel_floors +
+                               len * ff_vorbis_channel_layout_offsets[vc->audio_channels - 1][i];
+     }
++    /* ffdshow custom code */
++#if CONFIG_AUDIO_FLOAT
++    float_interleave(data, channel_ptrs, len, vc->audio_channels);
++    *data_size = len * sizeof(float) * vc->audio_channels;
++#else
+     vc->fmt_conv.float_to_int16_interleave(data, channel_ptrs, len,
+                                            vc->audio_channels);
+     *data_size = len * 2 * vc->audio_channels;
++#endif
+     return buf_size ;
+ }
+ // Close decoder
+ static av_cold int vorbis_decode_close(AVCodecContext *avccontext)
+ {
+     vorbis_context *vc = avccontext->priv_data;
+     vorbis_free(vc);
+     return 0 ;
+ }
+ AVCodec ff_vorbis_decoder = {
+     "vorbis",
+     AVMEDIA_TYPE_AUDIO,
+     CODEC_ID_VORBIS,
+     sizeof(vorbis_context),
+     vorbis_decode_init,
+     NULL,
+     vorbis_decode_close,
+     vorbis_decode_frame,
+     .long_name = NULL_IF_CONFIG_SMALL("Vorbis"),
+     .channel_layouts = ff_vorbis_channel_layouts,
+ };
index 0000000,74933af..d15d345
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1116 +1,1116 @@@
 - * This file is part of Libav.
+ /*
+  * copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org>
+  *
 - * 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
 -        av_log(avccontext, AV_LOG_ERROR, "Current Libav Vorbis encoder only supports 2 channels.\n");
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ /**
+  * @file
+  * Native Vorbis encoder.
+  * @author Oded Shimon <ods15@ods15.dyndns.org>
+  */
+ #include <float.h>
+ #include "avcodec.h"
+ #include "dsputil.h"
+ #include "fft.h"
+ #include "vorbis.h"
+ #include "vorbis_enc_data.h"
+ #define BITSTREAM_WRITER_LE
+ #include "put_bits.h"
+ #undef NDEBUG
+ #include <assert.h>
+ typedef struct {
+     int nentries;
+     uint8_t *lens;
+     uint32_t *codewords;
+     int ndimentions;
+     float min;
+     float delta;
+     int seq_p;
+     int lookup;
+     int *quantlist;
+     float *dimentions;
+     float *pow2;
+ } vorbis_enc_codebook;
+ typedef struct {
+     int dim;
+     int subclass;
+     int masterbook;
+     int *books;
+ } vorbis_enc_floor_class;
+ typedef struct {
+     int partitions;
+     int *partition_to_class;
+     int nclasses;
+     vorbis_enc_floor_class *classes;
+     int multiplier;
+     int rangebits;
+     int values;
+     vorbis_floor1_entry *list;
+ } vorbis_enc_floor;
+ typedef struct {
+     int type;
+     int begin;
+     int end;
+     int partition_size;
+     int classifications;
+     int classbook;
+     int8_t (*books)[8];
+     float (*maxes)[2];
+ } vorbis_enc_residue;
+ typedef struct {
+     int submaps;
+     int *mux;
+     int *floor;
+     int *residue;
+     int coupling_steps;
+     int *magnitude;
+     int *angle;
+ } vorbis_enc_mapping;
+ typedef struct {
+     int blockflag;
+     int mapping;
+ } vorbis_enc_mode;
+ typedef struct {
+     int channels;
+     int sample_rate;
+     int log2_blocksize[2];
+     FFTContext mdct[2];
+     const float *win[2];
+     int have_saved;
+     float *saved;
+     float *samples;
+     float *floor;  // also used for tmp values for mdct
+     float *coeffs; // also used for residue after floor
+     float quality;
+     int ncodebooks;
+     vorbis_enc_codebook *codebooks;
+     int nfloors;
+     vorbis_enc_floor *floors;
+     int nresidues;
+     vorbis_enc_residue *residues;
+     int nmappings;
+     vorbis_enc_mapping *mappings;
+     int nmodes;
+     vorbis_enc_mode *modes;
+     int64_t sample_count;
+ } vorbis_enc_context;
+ #define MAX_CHANNELS     2
+ #define MAX_CODEBOOK_DIM 8
+ #define MAX_FLOOR_CLASS_DIM  4
+ #define NUM_FLOOR_PARTITIONS 8
+ #define MAX_FLOOR_VALUES     (MAX_FLOOR_CLASS_DIM*NUM_FLOOR_PARTITIONS+2)
+ #define RESIDUE_SIZE           1600
+ #define RESIDUE_PART_SIZE      32
+ #define NUM_RESIDUE_PARTITIONS (RESIDUE_SIZE/RESIDUE_PART_SIZE)
+ static inline void put_codeword(PutBitContext *pb, vorbis_enc_codebook *cb,
+                                 int entry)
+ {
+     assert(entry >= 0);
+     assert(entry < cb->nentries);
+     assert(cb->lens[entry]);
+     put_bits(pb, cb->lens[entry], cb->codewords[entry]);
+ }
+ static int cb_lookup_vals(int lookup, int dimentions, int entries)
+ {
+     if (lookup == 1)
+         return ff_vorbis_nth_root(entries, dimentions);
+     else if (lookup == 2)
+         return dimentions *entries;
+     return 0;
+ }
+ static void ready_codebook(vorbis_enc_codebook *cb)
+ {
+     int i;
+     ff_vorbis_len2vlc(cb->lens, cb->codewords, cb->nentries);
+     if (!cb->lookup) {
+         cb->pow2 = cb->dimentions = NULL;
+     } else {
+         int vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries);
+         cb->dimentions = av_malloc(sizeof(float) * cb->nentries * cb->ndimentions);
+         cb->pow2 = av_mallocz(sizeof(float) * cb->nentries);
+         for (i = 0; i < cb->nentries; i++) {
+             float last = 0;
+             int j;
+             int div = 1;
+             for (j = 0; j < cb->ndimentions; j++) {
+                 int off;
+                 if (cb->lookup == 1)
+                     off = (i / div) % vals; // lookup type 1
+                 else
+                     off = i * cb->ndimentions + j; // lookup type 2
+                 cb->dimentions[i * cb->ndimentions + j] = last + cb->min + cb->quantlist[off] * cb->delta;
+                 if (cb->seq_p)
+                     last = cb->dimentions[i * cb->ndimentions + j];
+                 cb->pow2[i] += cb->dimentions[i * cb->ndimentions + j] * cb->dimentions[i * cb->ndimentions + j];
+                 div *= vals;
+             }
+             cb->pow2[i] /= 2.;
+         }
+     }
+ }
+ static void ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc)
+ {
+     int i;
+     assert(rc->type == 2);
+     rc->maxes = av_mallocz(sizeof(float[2]) * rc->classifications);
+     for (i = 0; i < rc->classifications; i++) {
+         int j;
+         vorbis_enc_codebook * cb;
+         for (j = 0; j < 8; j++)
+             if (rc->books[i][j] != -1)
+                 break;
+         if (j == 8) // zero
+             continue;
+         cb = &venc->codebooks[rc->books[i][j]];
+         assert(cb->ndimentions >= 2);
+         assert(cb->lookup);
+         for (j = 0; j < cb->nentries; j++) {
+             float a;
+             if (!cb->lens[j])
+                 continue;
+             a = fabs(cb->dimentions[j * cb->ndimentions]);
+             if (a > rc->maxes[i][0])
+                 rc->maxes[i][0] = a;
+             a = fabs(cb->dimentions[j * cb->ndimentions + 1]);
+             if (a > rc->maxes[i][1])
+                 rc->maxes[i][1] = a;
+         }
+     }
+     // small bias
+     for (i = 0; i < rc->classifications; i++) {
+         rc->maxes[i][0] += 0.8;
+         rc->maxes[i][1] += 0.8;
+     }
+ }
+ static void create_vorbis_context(vorbis_enc_context *venc,
+                                   AVCodecContext *avccontext)
+ {
+     vorbis_enc_floor   *fc;
+     vorbis_enc_residue *rc;
+     vorbis_enc_mapping *mc;
+     int i, book;
+     venc->channels    = avccontext->channels;
+     venc->sample_rate = avccontext->sample_rate;
+     venc->log2_blocksize[0] = venc->log2_blocksize[1] = 11;
+     venc->ncodebooks = FF_ARRAY_ELEMS(cvectors);
+     venc->codebooks  = av_malloc(sizeof(vorbis_enc_codebook) * venc->ncodebooks);
+     // codebook 0..14 - floor1 book, values 0..255
+     // codebook 15 residue masterbook
+     // codebook 16..29 residue
+     for (book = 0; book < venc->ncodebooks; book++) {
+         vorbis_enc_codebook *cb = &venc->codebooks[book];
+         int vals;
+         cb->ndimentions = cvectors[book].dim;
+         cb->nentries    = cvectors[book].real_len;
+         cb->min         = cvectors[book].min;
+         cb->delta       = cvectors[book].delta;
+         cb->lookup      = cvectors[book].lookup;
+         cb->seq_p       = 0;
+         cb->lens      = av_malloc(sizeof(uint8_t)  * cb->nentries);
+         cb->codewords = av_malloc(sizeof(uint32_t) * cb->nentries);
+         memcpy(cb->lens, cvectors[book].clens, cvectors[book].len);
+         memset(cb->lens + cvectors[book].len, 0, cb->nentries - cvectors[book].len);
+         if (cb->lookup) {
+             vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries);
+             cb->quantlist = av_malloc(sizeof(int) * vals);
+             for (i = 0; i < vals; i++)
+                 cb->quantlist[i] = cvectors[book].quant[i];
+         } else {
+             cb->quantlist = NULL;
+         }
+         ready_codebook(cb);
+     }
+     venc->nfloors = 1;
+     venc->floors  = av_malloc(sizeof(vorbis_enc_floor) * venc->nfloors);
+     // just 1 floor
+     fc = &venc->floors[0];
+     fc->partitions         = NUM_FLOOR_PARTITIONS;
+     fc->partition_to_class = av_malloc(sizeof(int) * fc->partitions);
+     fc->nclasses           = 0;
+     for (i = 0; i < fc->partitions; i++) {
+         static const int a[] = {0, 1, 2, 2, 3, 3, 4, 4};
+         fc->partition_to_class[i] = a[i];
+         fc->nclasses = FFMAX(fc->nclasses, fc->partition_to_class[i]);
+     }
+     fc->nclasses++;
+     fc->classes = av_malloc(sizeof(vorbis_enc_floor_class) * fc->nclasses);
+     for (i = 0; i < fc->nclasses; i++) {
+         vorbis_enc_floor_class * c = &fc->classes[i];
+         int j, books;
+         c->dim        = floor_classes[i].dim;
+         c->subclass   = floor_classes[i].subclass;
+         c->masterbook = floor_classes[i].masterbook;
+         books         = (1 << c->subclass);
+         c->books      = av_malloc(sizeof(int) * books);
+         for (j = 0; j < books; j++)
+             c->books[j] = floor_classes[i].nbooks[j];
+     }
+     fc->multiplier = 2;
+     fc->rangebits  = venc->log2_blocksize[0] - 1;
+     fc->values = 2;
+     for (i = 0; i < fc->partitions; i++)
+         fc->values += fc->classes[fc->partition_to_class[i]].dim;
+     fc->list = av_malloc(sizeof(vorbis_floor1_entry) * fc->values);
+     fc->list[0].x = 0;
+     fc->list[1].x = 1 << fc->rangebits;
+     for (i = 2; i < fc->values; i++) {
+         static const int a[] = {
+              93, 23,372,  6, 46,186,750, 14, 33, 65,
+             130,260,556,  3, 10, 18, 28, 39, 55, 79,
+             111,158,220,312,464,650,850
+         };
+         fc->list[i].x = a[i - 2];
+     }
+     ff_vorbis_ready_floor1_list(fc->list, fc->values);
+     venc->nresidues = 1;
+     venc->residues  = av_malloc(sizeof(vorbis_enc_residue) * venc->nresidues);
+     // single residue
+     rc = &venc->residues[0];
+     rc->type            = 2;
+     rc->begin           = 0;
+     rc->end             = 1600;
+     rc->partition_size  = 32;
+     rc->classifications = 10;
+     rc->classbook       = 15;
+     rc->books           = av_malloc(sizeof(*rc->books) * rc->classifications);
+     {
+         static const int8_t a[10][8] = {
+             { -1, -1, -1, -1, -1, -1, -1, -1, },
+             { -1, -1, 16, -1, -1, -1, -1, -1, },
+             { -1, -1, 17, -1, -1, -1, -1, -1, },
+             { -1, -1, 18, -1, -1, -1, -1, -1, },
+             { -1, -1, 19, -1, -1, -1, -1, -1, },
+             { -1, -1, 20, -1, -1, -1, -1, -1, },
+             { -1, -1, 21, -1, -1, -1, -1, -1, },
+             { 22, 23, -1, -1, -1, -1, -1, -1, },
+             { 24, 25, -1, -1, -1, -1, -1, -1, },
+             { 26, 27, 28, -1, -1, -1, -1, -1, },
+         };
+         memcpy(rc->books, a, sizeof a);
+     }
+     ready_residue(rc, venc);
+     venc->nmappings = 1;
+     venc->mappings  = av_malloc(sizeof(vorbis_enc_mapping) * venc->nmappings);
+     // single mapping
+     mc = &venc->mappings[0];
+     mc->submaps = 1;
+     mc->mux     = av_malloc(sizeof(int) * venc->channels);
+     for (i = 0; i < venc->channels; i++)
+         mc->mux[i] = 0;
+     mc->floor   = av_malloc(sizeof(int) * mc->submaps);
+     mc->residue = av_malloc(sizeof(int) * mc->submaps);
+     for (i = 0; i < mc->submaps; i++) {
+         mc->floor[i]   = 0;
+         mc->residue[i] = 0;
+     }
+     mc->coupling_steps = venc->channels == 2 ? 1 : 0;
+     mc->magnitude      = av_malloc(sizeof(int) * mc->coupling_steps);
+     mc->angle          = av_malloc(sizeof(int) * mc->coupling_steps);
+     if (mc->coupling_steps) {
+         mc->magnitude[0] = 0;
+         mc->angle[0]     = 1;
+     }
+     venc->nmodes = 1;
+     venc->modes  = av_malloc(sizeof(vorbis_enc_mode) * venc->nmodes);
+     // single mode
+     venc->modes[0].blockflag = 0;
+     venc->modes[0].mapping   = 0;
+     venc->have_saved = 0;
+     venc->saved      = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2);
+     venc->samples    = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]));
+     venc->floor      = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2);
+     venc->coeffs     = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2);
+     venc->win[0] = ff_vorbis_vwin[venc->log2_blocksize[0] - 6];
+     venc->win[1] = ff_vorbis_vwin[venc->log2_blocksize[1] - 6];
+     ff_mdct_init(&venc->mdct[0], venc->log2_blocksize[0], 0, 1.0);
+     ff_mdct_init(&venc->mdct[1], venc->log2_blocksize[1], 0, 1.0);
+ }
+ static void put_float(PutBitContext *pb, float f)
+ {
+     int exp, mant;
+     uint32_t res = 0;
+     mant = (int)ldexp(frexp(f, &exp), 20);
+     exp += 788 - 20;
+     if (mant < 0) {
+         res |= (1U << 31);
+         mant = -mant;
+     }
+     res |= mant | (exp << 21);
+     put_bits32(pb, res);
+ }
+ static void put_codebook_header(PutBitContext *pb, vorbis_enc_codebook *cb)
+ {
+     int i;
+     int ordered = 0;
+     put_bits(pb, 24, 0x564342); //magic
+     put_bits(pb, 16, cb->ndimentions);
+     put_bits(pb, 24, cb->nentries);
+     for (i = 1; i < cb->nentries; i++)
+         if (cb->lens[i] < cb->lens[i-1])
+             break;
+     if (i == cb->nentries)
+         ordered = 1;
+     put_bits(pb, 1, ordered);
+     if (ordered) {
+         int len = cb->lens[0];
+         put_bits(pb, 5, len - 1);
+         i = 0;
+         while (i < cb->nentries) {
+             int j;
+             for (j = 0; j+i < cb->nentries; j++)
+                 if (cb->lens[j+i] != len)
+                     break;
+             put_bits(pb, ilog(cb->nentries - i), j);
+             i += j;
+             len++;
+         }
+     } else {
+         int sparse = 0;
+         for (i = 0; i < cb->nentries; i++)
+             if (!cb->lens[i])
+                 break;
+         if (i != cb->nentries)
+             sparse = 1;
+         put_bits(pb, 1, sparse);
+         for (i = 0; i < cb->nentries; i++) {
+             if (sparse)
+                 put_bits(pb, 1, !!cb->lens[i]);
+             if (cb->lens[i])
+                 put_bits(pb, 5, cb->lens[i] - 1);
+         }
+     }
+     put_bits(pb, 4, cb->lookup);
+     if (cb->lookup) {
+         int tmp  = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries);
+         int bits = ilog(cb->quantlist[0]);
+         for (i = 1; i < tmp; i++)
+             bits = FFMAX(bits, ilog(cb->quantlist[i]));
+         put_float(pb, cb->min);
+         put_float(pb, cb->delta);
+         put_bits(pb, 4, bits - 1);
+         put_bits(pb, 1, cb->seq_p);
+         for (i = 0; i < tmp; i++)
+             put_bits(pb, bits, cb->quantlist[i]);
+     }
+ }
+ static void put_floor_header(PutBitContext *pb, vorbis_enc_floor *fc)
+ {
+     int i;
+     put_bits(pb, 16, 1); // type, only floor1 is supported
+     put_bits(pb, 5, fc->partitions);
+     for (i = 0; i < fc->partitions; i++)
+         put_bits(pb, 4, fc->partition_to_class[i]);
+     for (i = 0; i < fc->nclasses; i++) {
+         int j, books;
+         put_bits(pb, 3, fc->classes[i].dim - 1);
+         put_bits(pb, 2, fc->classes[i].subclass);
+         if (fc->classes[i].subclass)
+             put_bits(pb, 8, fc->classes[i].masterbook);
+         books = (1 << fc->classes[i].subclass);
+         for (j = 0; j < books; j++)
+             put_bits(pb, 8, fc->classes[i].books[j] + 1);
+     }
+     put_bits(pb, 2, fc->multiplier - 1);
+     put_bits(pb, 4, fc->rangebits);
+     for (i = 2; i < fc->values; i++)
+         put_bits(pb, fc->rangebits, fc->list[i].x);
+ }
+ static void put_residue_header(PutBitContext *pb, vorbis_enc_residue *rc)
+ {
+     int i;
+     put_bits(pb, 16, rc->type);
+     put_bits(pb, 24, rc->begin);
+     put_bits(pb, 24, rc->end);
+     put_bits(pb, 24, rc->partition_size - 1);
+     put_bits(pb, 6, rc->classifications - 1);
+     put_bits(pb, 8, rc->classbook);
+     for (i = 0; i < rc->classifications; i++) {
+         int j, tmp = 0;
+         for (j = 0; j < 8; j++)
+             tmp |= (rc->books[i][j] != -1) << j;
+         put_bits(pb, 3, tmp & 7);
+         put_bits(pb, 1, tmp > 7);
+         if (tmp > 7)
+             put_bits(pb, 5, tmp >> 3);
+     }
+     for (i = 0; i < rc->classifications; i++) {
+         int j;
+         for (j = 0; j < 8; j++)
+             if (rc->books[i][j] != -1)
+                 put_bits(pb, 8, rc->books[i][j]);
+     }
+ }
+ static int put_main_header(vorbis_enc_context *venc, uint8_t **out)
+ {
+     int i;
+     PutBitContext pb;
+     uint8_t buffer[50000] = {0}, *p = buffer;
+     int buffer_len = sizeof buffer;
+     int len, hlens[3];
+     // identification header
+     init_put_bits(&pb, p, buffer_len);
+     put_bits(&pb, 8, 1); //magic
+     for (i = 0; "vorbis"[i]; i++)
+         put_bits(&pb, 8, "vorbis"[i]);
+     put_bits32(&pb, 0); // version
+     put_bits(&pb,  8, venc->channels);
+     put_bits32(&pb, venc->sample_rate);
+     put_bits32(&pb, 0); // bitrate
+     put_bits32(&pb, 0); // bitrate
+     put_bits32(&pb, 0); // bitrate
+     put_bits(&pb,  4, venc->log2_blocksize[0]);
+     put_bits(&pb,  4, venc->log2_blocksize[1]);
+     put_bits(&pb,  1, 1); // framing
+     flush_put_bits(&pb);
+     hlens[0] = put_bits_count(&pb) >> 3;
+     buffer_len -= hlens[0];
+     p += hlens[0];
+     // comment header
+     init_put_bits(&pb, p, buffer_len);
+     put_bits(&pb, 8, 3); //magic
+     for (i = 0; "vorbis"[i]; i++)
+         put_bits(&pb, 8, "vorbis"[i]);
+     put_bits32(&pb, 0); // vendor length TODO
+     put_bits32(&pb, 0); // amount of comments
+     put_bits(&pb,  1, 1); // framing
+     flush_put_bits(&pb);
+     hlens[1] = put_bits_count(&pb) >> 3;
+     buffer_len -= hlens[1];
+     p += hlens[1];
+     // setup header
+     init_put_bits(&pb, p, buffer_len);
+     put_bits(&pb, 8, 5); //magic
+     for (i = 0; "vorbis"[i]; i++)
+         put_bits(&pb, 8, "vorbis"[i]);
+     // codebooks
+     put_bits(&pb, 8, venc->ncodebooks - 1);
+     for (i = 0; i < venc->ncodebooks; i++)
+         put_codebook_header(&pb, &venc->codebooks[i]);
+     // time domain, reserved, zero
+     put_bits(&pb,  6, 0);
+     put_bits(&pb, 16, 0);
+     // floors
+     put_bits(&pb, 6, venc->nfloors - 1);
+     for (i = 0; i < venc->nfloors; i++)
+         put_floor_header(&pb, &venc->floors[i]);
+     // residues
+     put_bits(&pb, 6, venc->nresidues - 1);
+     for (i = 0; i < venc->nresidues; i++)
+         put_residue_header(&pb, &venc->residues[i]);
+     // mappings
+     put_bits(&pb, 6, venc->nmappings - 1);
+     for (i = 0; i < venc->nmappings; i++) {
+         vorbis_enc_mapping *mc = &venc->mappings[i];
+         int j;
+         put_bits(&pb, 16, 0); // mapping type
+         put_bits(&pb, 1, mc->submaps > 1);
+         if (mc->submaps > 1)
+             put_bits(&pb, 4, mc->submaps - 1);
+         put_bits(&pb, 1, !!mc->coupling_steps);
+         if (mc->coupling_steps) {
+             put_bits(&pb, 8, mc->coupling_steps - 1);
+             for (j = 0; j < mc->coupling_steps; j++) {
+                 put_bits(&pb, ilog(venc->channels - 1), mc->magnitude[j]);
+                 put_bits(&pb, ilog(venc->channels - 1), mc->angle[j]);
+             }
+         }
+         put_bits(&pb, 2, 0); // reserved
+         if (mc->submaps > 1)
+             for (j = 0; j < venc->channels; j++)
+                 put_bits(&pb, 4, mc->mux[j]);
+         for (j = 0; j < mc->submaps; j++) {
+             put_bits(&pb, 8, 0); // reserved time configuration
+             put_bits(&pb, 8, mc->floor[j]);
+             put_bits(&pb, 8, mc->residue[j]);
+         }
+     }
+     // modes
+     put_bits(&pb, 6, venc->nmodes - 1);
+     for (i = 0; i < venc->nmodes; i++) {
+         put_bits(&pb, 1, venc->modes[i].blockflag);
+         put_bits(&pb, 16, 0); // reserved window type
+         put_bits(&pb, 16, 0); // reserved transform type
+         put_bits(&pb, 8, venc->modes[i].mapping);
+     }
+     put_bits(&pb, 1, 1); // framing
+     flush_put_bits(&pb);
+     hlens[2] = put_bits_count(&pb) >> 3;
+     len = hlens[0] + hlens[1] + hlens[2];
+     p = *out = av_mallocz(64 + len + len/255);
+     *p++ = 2;
+     p += av_xiphlacing(p, hlens[0]);
+     p += av_xiphlacing(p, hlens[1]);
+     buffer_len = 0;
+     for (i = 0; i < 3; i++) {
+         memcpy(p, buffer + buffer_len, hlens[i]);
+         p += hlens[i];
+         buffer_len += hlens[i];
+     }
+     return p - *out;
+ }
+ static float get_floor_average(vorbis_enc_floor * fc, float *coeffs, int i)
+ {
+     int begin = fc->list[fc->list[FFMAX(i-1, 0)].sort].x;
+     int end   = fc->list[fc->list[FFMIN(i+1, fc->values - 1)].sort].x;
+     int j;
+     float average = 0;
+     for (j = begin; j < end; j++)
+         average += fabs(coeffs[j]);
+     return average / (end - begin);
+ }
+ static void floor_fit(vorbis_enc_context *venc, vorbis_enc_floor *fc,
+                       float *coeffs, uint_fast16_t *posts, int samples)
+ {
+     int range = 255 / fc->multiplier + 1;
+     int i;
+     float tot_average = 0.;
+     float averages[MAX_FLOOR_VALUES];
+     for (i = 0; i < fc->values; i++) {
+         averages[i] = get_floor_average(fc, coeffs, i);
+         tot_average += averages[i];
+     }
+     tot_average /= fc->values;
+     tot_average /= venc->quality;
+     for (i = 0; i < fc->values; i++) {
+         int position  = fc->list[fc->list[i].sort].x;
+         float average = averages[i];
+         int j;
+         average = sqrt(tot_average * average) * pow(1.25f, position*0.005f); // MAGIC!
+         for (j = 0; j < range - 1; j++)
+             if (ff_vorbis_floor1_inverse_db_table[j * fc->multiplier] > average)
+                 break;
+         posts[fc->list[i].sort] = j;
+     }
+ }
+ static int render_point(int x0, int y0, int x1, int y1, int x)
+ {
+     return y0 +  (x - x0) * (y1 - y0) / (x1 - x0);
+ }
+ static void floor_encode(vorbis_enc_context *venc, vorbis_enc_floor *fc,
+                          PutBitContext *pb, uint_fast16_t *posts,
+                          float *floor, int samples)
+ {
+     int range = 255 / fc->multiplier + 1;
+     int coded[MAX_FLOOR_VALUES]; // first 2 values are unused
+     int i, counter;
+     put_bits(pb, 1, 1); // non zero
+     put_bits(pb, ilog(range - 1), posts[0]);
+     put_bits(pb, ilog(range - 1), posts[1]);
+     coded[0] = coded[1] = 1;
+     for (i = 2; i < fc->values; i++) {
+         int predicted = render_point(fc->list[fc->list[i].low].x,
+                                      posts[fc->list[i].low],
+                                      fc->list[fc->list[i].high].x,
+                                      posts[fc->list[i].high],
+                                      fc->list[i].x);
+         int highroom = range - predicted;
+         int lowroom = predicted;
+         int room = FFMIN(highroom, lowroom);
+         if (predicted == posts[i]) {
+             coded[i] = 0; // must be used later as flag!
+             continue;
+         } else {
+             if (!coded[fc->list[i].low ])
+                 coded[fc->list[i].low ] = -1;
+             if (!coded[fc->list[i].high])
+                 coded[fc->list[i].high] = -1;
+         }
+         if (posts[i] > predicted) {
+             if (posts[i] - predicted > room)
+                 coded[i] = posts[i] - predicted + lowroom;
+             else
+                 coded[i] = (posts[i] - predicted) << 1;
+         } else {
+             if (predicted - posts[i] > room)
+                 coded[i] = predicted - posts[i] + highroom - 1;
+             else
+                 coded[i] = ((predicted - posts[i]) << 1) - 1;
+         }
+     }
+     counter = 2;
+     for (i = 0; i < fc->partitions; i++) {
+         vorbis_enc_floor_class * c = &fc->classes[fc->partition_to_class[i]];
+         int k, cval = 0, csub = 1<<c->subclass;
+         if (c->subclass) {
+             vorbis_enc_codebook * book = &venc->codebooks[c->masterbook];
+             int cshift = 0;
+             for (k = 0; k < c->dim; k++) {
+                 int l;
+                 for (l = 0; l < csub; l++) {
+                     int maxval = 1;
+                     if (c->books[l] != -1)
+                         maxval = venc->codebooks[c->books[l]].nentries;
+                     // coded could be -1, but this still works, cause that is 0
+                     if (coded[counter + k] < maxval)
+                         break;
+                 }
+                 assert(l != csub);
+                 cval   |= l << cshift;
+                 cshift += c->subclass;
+             }
+             put_codeword(pb, book, cval);
+         }
+         for (k = 0; k < c->dim; k++) {
+             int book  = c->books[cval & (csub-1)];
+             int entry = coded[counter++];
+             cval >>= c->subclass;
+             if (book == -1)
+                 continue;
+             if (entry == -1)
+                 entry = 0;
+             put_codeword(pb, &venc->codebooks[book], entry);
+         }
+     }
+     ff_vorbis_floor1_render_list(fc->list, fc->values, posts, coded,
+                                  fc->multiplier, floor, samples);
+ }
+ static float *put_vector(vorbis_enc_codebook *book, PutBitContext *pb,
+                          float *num)
+ {
+     int i, entry = -1;
+     float distance = FLT_MAX;
+     assert(book->dimentions);
+     for (i = 0; i < book->nentries; i++) {
+         float * vec = book->dimentions + i * book->ndimentions, d = book->pow2[i];
+         int j;
+         if (!book->lens[i])
+             continue;
+         for (j = 0; j < book->ndimentions; j++)
+             d -= vec[j] * num[j];
+         if (distance > d) {
+             entry    = i;
+             distance = d;
+         }
+     }
+     put_codeword(pb, book, entry);
+     return &book->dimentions[entry * book->ndimentions];
+ }
+ static void residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc,
+                            PutBitContext *pb, float *coeffs, int samples,
+                            int real_ch)
+ {
+     int pass, i, j, p, k;
+     int psize      = rc->partition_size;
+     int partitions = (rc->end - rc->begin) / psize;
+     int channels   = (rc->type == 2) ? 1 : real_ch;
+     int classes[MAX_CHANNELS][NUM_RESIDUE_PARTITIONS];
+     int classwords = venc->codebooks[rc->classbook].ndimentions;
+     assert(rc->type == 2);
+     assert(real_ch == 2);
+     for (p = 0; p < partitions; p++) {
+         float max1 = 0., max2 = 0.;
+         int s = rc->begin + p * psize;
+         for (k = s; k < s + psize; k += 2) {
+             max1 = FFMAX(max1, fabs(coeffs[          k / real_ch]));
+             max2 = FFMAX(max2, fabs(coeffs[samples + k / real_ch]));
+         }
+         for (i = 0; i < rc->classifications - 1; i++)
+             if (max1 < rc->maxes[i][0] && max2 < rc->maxes[i][1])
+                 break;
+         classes[0][p] = i;
+     }
+     for (pass = 0; pass < 8; pass++) {
+         p = 0;
+         while (p < partitions) {
+             if (pass == 0)
+                 for (j = 0; j < channels; j++) {
+                     vorbis_enc_codebook * book = &venc->codebooks[rc->classbook];
+                     int entry = 0;
+                     for (i = 0; i < classwords; i++) {
+                         entry *= rc->classifications;
+                         entry += classes[j][p + i];
+                     }
+                     put_codeword(pb, book, entry);
+                 }
+             for (i = 0; i < classwords && p < partitions; i++, p++) {
+                 for (j = 0; j < channels; j++) {
+                     int nbook = rc->books[classes[j][p]][pass];
+                     vorbis_enc_codebook * book = &venc->codebooks[nbook];
+                     float *buf = coeffs + samples*j + rc->begin + p*psize;
+                     if (nbook == -1)
+                         continue;
+                     assert(rc->type == 0 || rc->type == 2);
+                     assert(!(psize % book->ndimentions));
+                     if (rc->type == 0) {
+                         for (k = 0; k < psize; k += book->ndimentions) {
+                             float *a = put_vector(book, pb, &buf[k]);
+                             int l;
+                             for (l = 0; l < book->ndimentions; l++)
+                                 buf[k + l] -= a[l];
+                         }
+                     } else {
+                         int s = rc->begin + p * psize, a1, b1;
+                         a1 = (s % real_ch) * samples;
+                         b1 =  s / real_ch;
+                         s  = real_ch * samples;
+                         for (k = 0; k < psize; k += book->ndimentions) {
+                             int dim, a2 = a1, b2 = b1;
+                             float vec[MAX_CODEBOOK_DIM], *pv = vec;
+                             for (dim = book->ndimentions; dim--; ) {
+                                 *pv++ = coeffs[a2 + b2];
+                                 if ((a2 += samples) == s) {
+                                     a2 = 0;
+                                     b2++;
+                                 }
+                             }
+                             pv = put_vector(book, pb, vec);
+                             for (dim = book->ndimentions; dim--; ) {
+                                 coeffs[a1 + b1] -= *pv++;
+                                 if ((a1 += samples) == s) {
+                                     a1 = 0;
+                                     b1++;
+                                 }
+                             }
+                         }
+                     }
+                 }
+             }
+         }
+     }
+ }
+ static int apply_window_and_mdct(vorbis_enc_context *venc, const signed short *audio,
+                                  int samples)
+ {
+     int i, j, channel;
+     const float * win = venc->win[0];
+     int window_len = 1 << (venc->log2_blocksize[0] - 1);
+     float n = (float)(1 << venc->log2_blocksize[0]) / 4.;
+     // FIXME use dsp
+     if (!venc->have_saved && !samples)
+         return 0;
+     if (venc->have_saved) {
+         for (channel = 0; channel < venc->channels; channel++)
+             memcpy(venc->samples + channel * window_len * 2,
+                    venc->saved + channel * window_len, sizeof(float) * window_len);
+     } else {
+         for (channel = 0; channel < venc->channels; channel++)
+             memset(venc->samples + channel * window_len * 2, 0,
+                    sizeof(float) * window_len);
+     }
+     if (samples) {
+         for (channel = 0; channel < venc->channels; channel++) {
+             float * offset = venc->samples + channel*window_len*2 + window_len;
+             j = channel;
+             for (i = 0; i < samples; i++, j += venc->channels)
+                 offset[i] = audio[j] / 32768. / n * win[window_len - i - 1];
+         }
+     } else {
+         for (channel = 0; channel < venc->channels; channel++)
+             memset(venc->samples + channel * window_len * 2 + window_len,
+                    0, sizeof(float) * window_len);
+     }
+     for (channel = 0; channel < venc->channels; channel++)
+         venc->mdct[0].mdct_calc(&venc->mdct[0], venc->coeffs + channel * window_len,
+                      venc->samples + channel * window_len * 2);
+     if (samples) {
+         for (channel = 0; channel < venc->channels; channel++) {
+             float *offset = venc->saved + channel * window_len;
+             j = channel;
+             for (i = 0; i < samples; i++, j += venc->channels)
+                 offset[i] = audio[j] / 32768. / n * win[i];
+         }
+         venc->have_saved = 1;
+     } else {
+         venc->have_saved = 0;
+     }
+     return 1;
+ }
+ static av_cold int vorbis_encode_init(AVCodecContext *avccontext)
+ {
+     vorbis_enc_context *venc = avccontext->priv_data;
+     if (avccontext->channels != 2) {
++        av_log(avccontext, AV_LOG_ERROR, "Current FFmpeg Vorbis encoder only supports 2 channels.\n");
+         return -1;
+     }
+     create_vorbis_context(venc, avccontext);
+     if (avccontext->flags & CODEC_FLAG_QSCALE)
+         venc->quality = avccontext->global_quality / (float)FF_QP2LAMBDA / 10.;
+     else
+         venc->quality = 0.03;
+     venc->quality *= venc->quality;
+     avccontext->extradata_size = put_main_header(venc, (uint8_t**)&avccontext->extradata);
+     avccontext->frame_size     = 1 << (venc->log2_blocksize[0] - 1);
+     avccontext->coded_frame            = avcodec_alloc_frame();
+     avccontext->coded_frame->key_frame = 1;
+     return 0;
+ }
+ static int vorbis_encode_frame(AVCodecContext *avccontext,
+                                unsigned char *packets,
+                                int buf_size, void *data)
+ {
+     vorbis_enc_context *venc = avccontext->priv_data;
+     const signed short *audio = data;
+     int samples = data ? avccontext->frame_size : 0;
+     vorbis_enc_mode *mode;
+     vorbis_enc_mapping *mapping;
+     PutBitContext pb;
+     int i;
+     if (!apply_window_and_mdct(venc, audio, samples))
+         return 0;
+     samples = 1 << (venc->log2_blocksize[0] - 1);
+     init_put_bits(&pb, packets, buf_size);
+     put_bits(&pb, 1, 0); // magic bit
+     put_bits(&pb, ilog(venc->nmodes - 1), 0); // 0 bits, the mode
+     mode    = &venc->modes[0];
+     mapping = &venc->mappings[mode->mapping];
+     if (mode->blockflag) {
+         put_bits(&pb, 1, 0);
+         put_bits(&pb, 1, 0);
+     }
+     for (i = 0; i < venc->channels; i++) {
+         vorbis_enc_floor *fc = &venc->floors[mapping->floor[mapping->mux[i]]];
+         uint_fast16_t posts[MAX_FLOOR_VALUES];
+         floor_fit(venc, fc, &venc->coeffs[i * samples], posts, samples);
+         floor_encode(venc, fc, &pb, posts, &venc->floor[i * samples], samples);
+     }
+     for (i = 0; i < venc->channels * samples; i++)
+         venc->coeffs[i] /= venc->floor[i];
+     for (i = 0; i < mapping->coupling_steps; i++) {
+         float *mag = venc->coeffs + mapping->magnitude[i] * samples;
+         float *ang = venc->coeffs + mapping->angle[i]     * samples;
+         int j;
+         for (j = 0; j < samples; j++) {
+             float a = ang[j];
+             ang[j] -= mag[j];
+             if (mag[j] > 0)
+                 ang[j] = -ang[j];
+             if (ang[j] < 0)
+                 mag[j] = a;
+         }
+     }
+     residue_encode(venc, &venc->residues[mapping->residue[mapping->mux[0]]],
+                    &pb, venc->coeffs, samples, venc->channels);
+     avccontext->coded_frame->pts = venc->sample_count;
+     venc->sample_count += avccontext->frame_size;
+     flush_put_bits(&pb);
+     return put_bits_count(&pb) >> 3;
+ }
+ static av_cold int vorbis_encode_close(AVCodecContext *avccontext)
+ {
+     vorbis_enc_context *venc = avccontext->priv_data;
+     int i;
+     if (venc->codebooks)
+         for (i = 0; i < venc->ncodebooks; i++) {
+             av_freep(&venc->codebooks[i].lens);
+             av_freep(&venc->codebooks[i].codewords);
+             av_freep(&venc->codebooks[i].quantlist);
+             av_freep(&venc->codebooks[i].dimentions);
+             av_freep(&venc->codebooks[i].pow2);
+         }
+     av_freep(&venc->codebooks);
+     if (venc->floors)
+         for (i = 0; i < venc->nfloors; i++) {
+             int j;
+             if (venc->floors[i].classes)
+                 for (j = 0; j < venc->floors[i].nclasses; j++)
+                     av_freep(&venc->floors[i].classes[j].books);
+             av_freep(&venc->floors[i].classes);
+             av_freep(&venc->floors[i].partition_to_class);
+             av_freep(&venc->floors[i].list);
+         }
+     av_freep(&venc->floors);
+     if (venc->residues)
+         for (i = 0; i < venc->nresidues; i++) {
+             av_freep(&venc->residues[i].books);
+             av_freep(&venc->residues[i].maxes);
+         }
+     av_freep(&venc->residues);
+     if (venc->mappings)
+         for (i = 0; i < venc->nmappings; i++) {
+             av_freep(&venc->mappings[i].mux);
+             av_freep(&venc->mappings[i].floor);
+             av_freep(&venc->mappings[i].residue);
+             av_freep(&venc->mappings[i].magnitude);
+             av_freep(&venc->mappings[i].angle);
+         }
+     av_freep(&venc->mappings);
+     av_freep(&venc->modes);
+     av_freep(&venc->saved);
+     av_freep(&venc->samples);
+     av_freep(&venc->floor);
+     av_freep(&venc->coeffs);
+     ff_mdct_end(&venc->mdct[0]);
+     ff_mdct_end(&venc->mdct[1]);
+     av_freep(&avccontext->coded_frame);
+     av_freep(&avccontext->extradata);
+     return 0 ;
+ }
+ AVCodec ff_vorbis_encoder = {
+     "vorbis",
+     AVMEDIA_TYPE_AUDIO,
+     CODEC_ID_VORBIS,
+     sizeof(vorbis_enc_context),
+     vorbis_encode_init,
+     vorbis_encode_frame,
+     vorbis_encode_close,
+     .capabilities= CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL,
+     .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
+     .long_name = NULL_IF_CONFIG_SMALL("Vorbis"),
+ };
Simple merge
Simple merge
Simple merge
@@@ -2414,9 -2414,9 +2414,9 @@@ static int mov_read_packet(AVFormatCont
          mov->found_mdat = 0;
          if (s->pb->seekable||
              mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 ||
 -            s->pb->eof_reached)
 +            url_feof(s->pb))
              return AVERROR_EOF;
-         av_dlog(s, "read fragments, offset 0x%llx\n", avio_tell(s->pb));
+         av_dlog(s, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
          goto retry;
      }
      sc = st->priv_data;
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc tools/patcheck
Simple merge