[FFmpeg-devel] Help needed with a codec

Daniel Verkamp daniel
Thu Sep 3 21:30:27 CEST 2009


On Thu, Sep 3, 2009 at 7:51 AM, Kostya<kostya.shishkov at gmail.com> wrote:
> Here is a bit of code I wrote in my free time.
> I suspect I won't have it (free time) until winter, so I release this in
> a hope it will be useful for somebody and that somebody will finish and
> commit it.
>
> It seems to play Bink files I have at hand with medium artifacts that
> are likely caused by slightly different DCT approach.
> Bink has predefined fixed-point (32.16) quantization tables and dequants
> coefficients during DCT as (coef[i] * quant[i]) >> 11. I have to shift
> by 16 to use IDCT from dsputil, so quality is degraded.
>
> Also this code needs Bink demuxer <adsense>and plays better with Bink
> audio decoder</adsense> by Peter Ross, so if you want it working, kick
> him or Daniel Verkamp who promised to finish Bink decoder.
>

Great work!

Slightly updated patch (including demuxer and audio decoder):

- Decode U and V planes in the correct order
- Set video stream duration
- Pass video flags in extradata, which is used to...
- Decode only the Y plane of grayscale files (fixes crash)

More fixes and split patches coming soon...

If the hunks adding new codec IDs and Smacker demuxer changes (already
OK'd in other thread) could be committed, that would be helpful.

And just as a "yes, it works":
http://drv.nu/temp/bink/ffplay-bink-dnf.png
(screenshot of E3 2001 Duke Nukem Forever trailer, extracted from
self-playing Bink EXE)

Thanks,
-- Daniel Verkamp
-------------- next part --------------
diff --git a/configure b/configure
index 4a8d523..819d96f 100755
--- a/configure
+++ b/configure
@@ -97,6 +97,7 @@ show_help(){
   echo "  --disable-fastdiv        disable table-based division"
   echo "  --enable-small           optimize for size instead of speed"
   echo "  --disable-aandct         disable AAN DCT code"
+  echo "  --disable-dct            disable DCT code"
   echo "  --disable-fft            disable FFT code"
   echo "  --disable-golomb         disable Golomb code"
   echo "  --disable-mdct           disable MDCT code"
@@ -807,6 +808,7 @@ CONFIG_LIST="
     avisynth
     beos_netserver
     bzlib
+    dct
     fastdiv
     ffmpeg
     ffplay
@@ -1066,6 +1068,8 @@ aac_decoder_select="fft mdct"
 aac_encoder_select="fft mdct"
 ac3_decoder_select="fft mdct"
 atrac3_decoder_select="fft mdct"
+binkaudio1_decoder_select="rdft"
+binkaudio2_decoder_select="dct"
 cavs_decoder_select="golomb"
 cook_decoder_select="fft mdct"
 cscd_decoder_suggest="zlib"
diff --git a/doc/general.texi b/doc/general.texi
index 18dd43e..8dfe95d 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -57,6 +57,8 @@ library:
     @tab Audio and video format used in some games by Beam Software.
 @item Bethesda Softworks VID    @tab   @tab X
     @tab Used in some games from Bethesda Softworks.
+ at item Bink                      @tab   @tab X
+    @tab Multimedia format used by many games.
 @item Brute Force & Ignorance   @tab   @tab X
     @tab Used in the game Flash Traffic: City of Angels.
 @item Interplay C93             @tab   @tab X
@@ -531,6 +533,8 @@ following image formats are supported:
 @item Apple lossless audio   @tab  X  @tab  X
     @tab QuickTime fourcc 'alac'
 @item Atrac 3                @tab     @tab  X
+ at item Bink Audio             @tab     @tab  X
+    @tab Used in Bink and Smacker files in many games.
 @item Delphine Software International CIN audio  @tab     @tab  X
     @tab Codec used in Delphine Software International games.
 @item COOK                   @tab     @tab  X
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 57ae895..2f91f2d 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -27,6 +27,7 @@ OBJS = allcodecs.o                                                      \
 # parts needed for many different codecs
 OBJS-$(CONFIG_AANDCT)                  += aandcttab.o
 OBJS-$(CONFIG_ENCODERS)                += faandct.o jfdctfst.o jfdctint.o
+OBJS-$(CONFIG_DCT)                     += dct.o
 OBJS-$(CONFIG_FFT)                     += fft.o
 OBJS-$(CONFIG_GOLOMB)                  += golomb.o
 OBJS-$(CONFIG_MDCT)                    += mdct.o
@@ -52,6 +53,9 @@ OBJS-$(CONFIG_ATRAC3_DECODER)          += atrac3.o
 OBJS-$(CONFIG_AVS_DECODER)             += avs.o
 OBJS-$(CONFIG_BETHSOFTVID_DECODER)     += bethsoftvideo.o
 OBJS-$(CONFIG_BFI_DECODER)             += bfi.o
+OBJS-$(CONFIG_BINK_DECODER)            += bink.o
+OBJS-$(CONFIG_BINKAUDIO1_DECODER)      += binkaudio.o wma.o
+OBJS-$(CONFIG_BINKAUDIO2_DECODER)      += binkaudio.o wma.o
 OBJS-$(CONFIG_BMP_DECODER)             += bmp.o msrledec.o
 OBJS-$(CONFIG_BMP_ENCODER)             += bmpenc.o
 OBJS-$(CONFIG_C93_DECODER)             += c93.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index e0007d9..9e83017 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -68,6 +68,7 @@ void avcodec_register_all(void)
     REGISTER_DECODER (AVS, avs);
     REGISTER_DECODER (BETHSOFTVID, bethsoftvid);
     REGISTER_DECODER (BFI, bfi);
+    REGISTER_DECODER (BINK, bink);
     REGISTER_ENCDEC  (BMP, bmp);
     REGISTER_DECODER (C93, c93);
     REGISTER_DECODER (CAVS, cavs);
@@ -200,6 +201,8 @@ void avcodec_register_all(void)
     REGISTER_ENCDEC  (ALAC, alac);
     REGISTER_DECODER (APE, ape);
     REGISTER_DECODER (ATRAC3, atrac3);
+    REGISTER_DECODER (BINKAUDIO1, binkaudio1);
+    REGISTER_DECODER (BINKAUDIO2, binkaudio2);
     REGISTER_DECODER (COOK, cook);
     REGISTER_DECODER (DCA, dca);
     REGISTER_DECODER (DSICINAUDIO, dsicinaudio);
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index a96726c..cace115 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -198,6 +198,7 @@ enum CodecID {
     CODEC_ID_V210,
     CODEC_ID_DPX,
     CODEC_ID_MAD,
+    CODEC_ID_BINKVIDEO,
 
     /* various PCM "codecs" */
     CODEC_ID_PCM_S16LE= 0x10000,
@@ -320,6 +321,8 @@ enum CodecID {
     CODEC_ID_TWINVQ,
     CODEC_ID_TRUEHD,
     CODEC_ID_MP4ALS,
+    CODEC_ID_BINKAUDIO1,
+    CODEC_ID_BINKAUDIO2,
 
     /* subtitle codecs */
     CODEC_ID_DVD_SUBTITLE= 0x17000,
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
new file mode 100644
index 0000000..86bbf15
--- /dev/null
+++ b/libavcodec/bink.c
@@ -0,0 +1,928 @@
+/*
+ * Bink video decoder
+ * Copyright (c) 2009 Konstantin Shishkov
+ *
+ * This file is part of FFmpeg.
+ *
+ * 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.
+ *
+ * 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
+ */
+
+#include "avcodec.h"
+#include "dsputil.h"
+#include "binkdata.h"
+#include "mathops.h"
+
+#define ALT_BITSTREAM_READER_LE
+#include "get_bits.h"
+
+static VLC bink_trees[16];
+
+/**
+ * IDs for different data types used in Bink video codec
+ */
+enum Sources {
+    BINK_SRC_BLOCK_TYPES = 0, ///< 8x8 block types
+    BINK_SRC_SUB_BLOCK_TYPES, ///< 16x16 block types (a subset of 8x8 block types)
+    BINK_SRC_COLORS,          ///< pixel values used for different block types
+    BINK_SRC_PATTERN,         ///< 8-bit values for 2-colour pattern fill
+    BINK_SRC_X_OFF,           ///< X components of motion value
+    BINK_SRC_Y_OFF,           ///< Y components of motion value
+    BINK_SRC_INTRA_DC,        ///< DC values for intrablocks with DCT
+    BINK_SRC_INTER_DC,        ///< DC values for intrablocks with DCT
+    BINK_SRC_RUN,             ///< run lengths for special fill block
+
+    BINK_NB_SRC
+};
+
+/**
+ * data needed to decode 4-bit Huffman-coded value
+ */
+typedef struct Tree {
+    int     vlc_num;  ///< tree number (in bink_trees[])
+    uint8_t syms[16]; ///< leaf value to symbol mapping
+} Tree;
+
+#define GET_HUFF(gb, tree)  (tree).syms[get_vlc2(gb, bink_trees[(tree).vlc_num].table,\
+                                                 bink_trees[(tree).vlc_num].bits, 1)]
+
+/**
+ * data structure used for decoding single Bink data type
+ */
+typedef struct Bundle {
+    int     len;       ///< length of number of entries to decode (in bits)
+    Tree    tree;      ///< Huffman tree-related data
+    uint8_t *data;     ///< buffer for decoded symbols
+    uint8_t *data_end; ///< buffer end
+    uint8_t *cur_dec;  ///< pointer to the not yet decoded part of the buffer
+    uint8_t *cur_ptr;  ///< pointer to the data that is not read from buffer yet
+} Bundle;
+
+/*
+ * Decoder context
+ */
+typedef struct BinkContext {
+    AVCodecContext *avctx;
+    DSPContext     dsp;
+    AVFrame        pic, last;
+    int            version;              ///< internal Bink file version
+    int            flags;
+    ScanTable      scantable;            ///< permutated scantable for DCT coeffs decoding
+
+    Bundle         bundle[BINK_NB_SRC];  ///< bundles for decoding all data types
+    Tree           col_high[16];         ///< trees for decoding high nibble in "colours" data type
+    int            col_lastval;          ///< value of last decoded high nibble in "colours" data type
+} BinkContext;
+
+/**
+ * Bink video block types
+ */
+enum BlockTypes {
+    SKIP_BLOCK = 0, ///< skipped block
+    SCALED_BLOCK,   ///< block has size 16x16
+    MOTION_BLOCK,   ///< block is copied from previous frame with some offset
+    RUN_BLOCK,      ///< block is composed from runs of colours with custom scan order
+    RESIDUE_BLOCK,  ///< motion block with some difference added
+    INTRA_BLOCK,    ///< intra DCT block
+    FILL_BLOCK,     ///< block is filled with single colour
+    INTER_BLOCK,    ///< motion block with DCT applied to the difference
+    PATTERN_BLOCK,  ///< block is filled with two colours following custom pattern
+    RAW_BLOCK,      ///< uncoded 8x8 block
+};
+
+enum BinkVideoFlags {
+    BINK_GRAYSCALE = (1 << 17),
+};
+
+/**
+ * Initializes length length in all bundles.
+ *
+ * @param c     decoder context
+ * @param width plane width
+ * @param bw    plane width in 8x8 blocks
+ */
+static void init_lengths(BinkContext *c, int width, int bw)
+{
+    c->bundle[BINK_SRC_BLOCK_TYPES].len = av_log2((width >> 3) + 511) + 1;
+    
+    c->bundle[BINK_SRC_SUB_BLOCK_TYPES].len = av_log2((width >> 4) + 511) + 1;
+
+    c->bundle[BINK_SRC_COLORS].len = av_log2((width >> 3)*64 + 511) + 1;
+
+    c->bundle[BINK_SRC_INTRA_DC].len =
+    c->bundle[BINK_SRC_INTER_DC].len =
+    c->bundle[BINK_SRC_X_OFF].len =
+    c->bundle[BINK_SRC_Y_OFF].len = av_log2((width >> 3) + 511) + 1;
+
+    c->bundle[BINK_SRC_PATTERN].len = av_log2((bw << 3) + 511) + 1;
+
+    c->bundle[BINK_SRC_RUN].len = av_log2((width >> 3)*48 + 511) + 1;
+}
+
+/**
+ * Allocates memory for bundles.
+ *
+ * @param c decoder context
+ */
+static av_cold void init_bundles(BinkContext *c)
+{
+    int bw, bh, blocks;
+    int i;
+
+    bw = (c->avctx->width  + 7) >> 3;
+    bh = (c->avctx->height + 7) >> 3;
+    blocks = bw * bh;
+
+    for (i = 0; i < BINK_NB_SRC; i++) {
+        c->bundle[i].data = av_malloc(blocks * 64);
+        c->bundle[i].data_end = c->bundle[i].data + blocks * 64;
+    }
+}
+
+/**
+ * Frees memory used by bundles.
+ *
+ * @param c decoder context
+ */
+static av_cold void free_bundles(BinkContext *c)
+{
+    int i;
+    for (i = 0; i < BINK_NB_SRC; i++)
+        av_freep(&c->bundle[i].data);
+}
+
+/**
+ * Merges two consequent lists of equal size depending on bits read.
+ *
+ * @param gb   context for reading bits
+ * @param dst  buffer where merged list will be written to
+ * @param src  pointer to the head of the first list (the second lists starts at src+size)
+ * @param size input lists size
+ */
+static void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size)
+{
+    uint8_t *src2 = src + size;
+    int size2 = size;
+
+    do {
+        if (!get_bits1(gb)) {
+            *dst++ = *src++;
+            size--;
+        } else {
+            *dst++ = *src2++;
+            size2--;
+        }
+    } while (size && size2);
+
+    while (size--)
+        *dst++ = *src++;
+    while (size2--)
+        *dst++ = *src2++;
+}
+
+/**
+ * Reads information about Huffman tree used to decode data.
+ *
+ * @param gb   context for reading bits
+ * @param tree pointer for storing tree data
+ */
+static void read_tree(GetBitContext *gb, Tree *tree)
+{
+    uint8_t tmp1[16], tmp2[16], *in = tmp1, *out = tmp2;
+    int i, t, len;
+
+    tree->vlc_num = get_bits(gb, 4);
+    if (!tree->vlc_num) {
+        for (i = 0; i < 16; i++)
+            tree->syms[i] = i;
+        return;
+    }
+    if (get_bits1(gb)) {
+        len = get_bits(gb, 3);
+        memset(tmp1, 0, sizeof(tmp1));
+        for (i = 0; i <= len; i++) {
+            tree->syms[i] = get_bits(gb, 4);
+            tmp1[tree->syms[i]] = 1;
+        }
+        for (i = 0; i < 16; i++)
+            if (!tmp1[i])
+                tree->syms[++len] = i;
+    } else {
+        len = get_bits(gb, 2);
+        for (i = 0; i < 16; i++)
+            in[i] = i;
+        for (i = 0; i <= len; i++) {
+            int size = 1 << i;
+            for (t = 0; t < 16; t += size << 1)
+                merge(gb, out + t, in + t, size);
+            FFSWAP(uint8_t*, in, out);
+        }
+        memcpy(tree->syms, in, 16);
+    }
+}
+
+/**
+ * Prepares bundle for decoding data.
+ *
+ * @param gb          context for reading bits
+ * @param c           decoder context
+ * @param bundle_num  number of the bundle to initialize
+ */
+static void read_bundle(GetBitContext *gb, BinkContext *c, int bundle_num)
+{
+    int i;
+
+    if (bundle_num == BINK_SRC_COLORS) {
+        for (i = 0; i < 16; i++)
+            read_tree(gb, &c->col_high[i]);
+        c->col_lastval = 0;
+    }
+    if (bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC)
+        read_tree(gb, &c->bundle[bundle_num].tree);
+    c->bundle[bundle_num].cur_dec =
+    c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data;
+}
+
+/**
+ * common check before starting decoding bundle data
+ *
+ * @param gb context for reading bits
+ * @param b  bundle
+ * @param t  variable where number of elements to decode will be stored
+ */
+#define CHECK_READ_VAL(gb, b, t) \
+    if (!b->cur_dec || (b->cur_dec > b->cur_ptr)) \
+        return 0; \
+    t = get_bits(gb, b->len); \
+    if (!t) { \
+        b->cur_dec = NULL; \
+        return 0; \
+    } \
+
+static int read_runs(GetBitContext *gb, Bundle *b)
+{
+    int i, t, v;
+
+    CHECK_READ_VAL(gb, b, t);
+    if (get_bits1(gb)) {
+        v = get_bits(gb, 4);
+        if (b->cur_dec + t > b->data_end)
+            return -1;
+        memset(b->cur_dec, v, t);
+        b->cur_dec += t;
+    } else {
+        for (i = 0; i < t; i++) {
+            v = GET_HUFF(gb, b->tree);
+            *b->cur_dec++ = v;
+        }
+    }
+    return 0;
+}
+
+static int read_motion_values(GetBitContext *gb, Bundle *b)
+{
+    int i, t, v;
+
+    CHECK_READ_VAL(gb, b, t);
+    if (get_bits1(gb)) {
+        v = get_bits(gb, 4);
+        if (v && get_bits1(gb))
+            v = -v;
+        if (b->cur_dec + t > b->data_end)
+            return -1;
+        memset(b->cur_dec, v, t);
+        b->cur_dec += t;
+    } else {
+        for (i = 0; i < t; i++) {
+            v = GET_HUFF(gb, b->tree);
+            if (v && get_bits1(gb))
+                v = -v;
+            *b->cur_dec++ = v;
+        }
+    }
+    return 0;
+}
+
+const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 };
+
+static int read_block_types(GetBitContext *gb, Bundle *b)
+{
+    int i, t, v;
+    int last = 0;
+
+    CHECK_READ_VAL(gb, b, t);
+    if (get_bits1(gb)) {
+        v = get_bits(gb, 4);
+        memset(b->cur_dec, v, t);
+        b->cur_dec += t;
+    } else {
+        for (i = 0; i < t; i++) {
+            v = GET_HUFF(gb, b->tree);
+            if (v < 12) {
+                last = v;
+                *b->cur_dec++ = v;
+            } else {
+                int run = bink_rlelens[v - 12];
+
+                memset(b->cur_dec, last, run);
+                b->cur_dec += run;
+                i += run - 1;
+            }
+        }
+    }
+    return 0;
+}
+
+static int read_patterns(GetBitContext *gb, Bundle *b)
+{
+    int i, t, v;
+
+    CHECK_READ_VAL(gb, b, t);
+    for (i = 0; i < t; i++) {
+        v  = GET_HUFF(gb, b->tree);
+        v |= GET_HUFF(gb, b->tree) << 4;
+        *b->cur_dec++ = v;
+    }
+
+    return 0;
+}
+
+static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c)
+{
+    int i, t, v, v2;
+
+    CHECK_READ_VAL(gb, b, t);
+    if (get_bits1(gb)) {
+        v2 = GET_HUFF(gb, c->col_high[c->col_lastval]);
+        c->col_lastval = v2;
+        v = GET_HUFF(gb, b->tree);
+        v = (v2 << 4) | v;
+        if (c->version < 'i') {
+            if (v & 0x80)
+                v = -(v & 0x7F);
+            v += 0x80;
+        }
+        memset(b->cur_dec, v, t);
+        b->cur_dec += t;
+    } else {
+        for (i = 0; i < t; i++) {
+            v2 = GET_HUFF(gb, c->col_high[c->col_lastval]);
+            c->col_lastval = v2;
+            v = GET_HUFF(gb, b->tree);
+            v = (v2 << 4) | v;
+            if (c->version < 'i') {
+                if (v & 0x80)
+                    v = -(v & 0x7F);
+                v += 0x80;
+            }
+            *b->cur_dec++ = v;
+        }
+    }
+    return 0;
+}
+
+/** number of bits used to store first DC value in bundle */
+#define DC_START_BITS 11
+
+static int read_dcs(GetBitContext *gb, Bundle *b, int start_bits, int has_sign)
+{
+    int i, j, len, len2, bsize, v, v2;
+    int16_t *dst = (int16_t*)b->cur_dec;
+
+    CHECK_READ_VAL(gb, b, len);
+    if (has_sign) {
+        v = get_bits(gb, start_bits - 1);
+        if (v && get_bits1(gb))
+            v = -v;
+    } else {
+        v = get_bits(gb, start_bits);
+    }
+    *dst++ = v;
+    len--;
+    for (i = 0; i < len; i += 8) {
+        len2 = FFMIN(len - i, 8);
+        bsize = get_bits(gb, 4);
+        if (bsize) {
+            for (j = 0; j < len2; j++) {
+                v2 = get_bits(gb, bsize);
+                if (v2 && get_bits1(gb))
+                    v2 = -v2;
+                v += v2;
+                *dst++ = v;
+                if (v < -32768 || v > 32767)
+                    return -1;
+            }
+        } else {
+            for (j = 0; j < len2; j++)
+                *dst++ = v;
+        }
+    }
+
+    b->cur_dec = (uint8_t*)dst;
+    return 0;
+}
+
+/**
+ * Retrieves next value from bundle.
+ *
+ * @param c      decoder context
+ * @param bundle bundle number
+ */
+static inline int get_value(BinkContext *c, int bundle)
+{
+    int16_t ret;
+
+    if (bundle < BINK_SRC_X_OFF || bundle == BINK_SRC_RUN)
+        return *c->bundle[bundle].cur_ptr++;
+    if (bundle == BINK_SRC_X_OFF || bundle == BINK_SRC_Y_OFF)
+        return (int8_t)*c->bundle[bundle].cur_ptr++;
+    ret = *(int16_t*)c->bundle[bundle].cur_ptr;
+    c->bundle[bundle].cur_ptr += 2;
+    return ret;
+}
+
+/**
+ * Reads 8x8 block of DCT coefficients.
+ *
+ * @param gb    context for reading bits
+ * @param block place for storing coefficients
+ * @param scan  scan order table
+ * @return 0 for success, negative value in other cases
+ */
+static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *scan)
+{
+    int mode_list[128];
+    int i, t, mask, bits, ccoef, mode;
+    int list_start = 64, list_end = 64, list_pos;
+
+    mode_list[list_end++] = ( 4 << 2) | 0;
+    mode_list[list_end++] = (24 << 2) | 0;
+    mode_list[list_end++] = (44 << 2) | 0;
+    mode_list[list_end++] = ( 1 << 2) | 3;
+    mode_list[list_end++] = ( 2 << 2) | 3;
+    mode_list[list_end++] = ( 3 << 2) | 3;
+
+    bits = get_bits(gb, 4) - 1;
+    for (mask = 1 << bits; bits >= 0; mask >>= 1, bits--) {
+        list_pos = list_start;
+        while (list_pos < list_end) {
+            if (!mode_list[list_pos] || !get_bits1(gb)) {
+                list_pos++;
+                continue;
+            }
+            ccoef = mode_list[list_pos] >> 2;
+            mode  = mode_list[list_pos] & 3;
+            switch (mode) {
+            case 0:
+            case 2:
+                if (!mode) {
+                    mode_list[list_pos] = ((ccoef + 4) << 2) | 1;
+                } else {
+                    mode_list[list_pos++] = 0;
+                }
+                for (i = 0; i < 4; i++, ccoef++) {
+                    if (get_bits1(gb)) {
+                        mode_list[--list_start] = (ccoef << 2) | 3;
+                    } else {
+                        int t;
+                        if (!bits) {
+                            t = get_bits1(gb) ? -1 : 1;
+                        } else {
+                            t = get_bits(gb, bits) | mask;
+                            if (get_bits1(gb))
+                                t = -t;
+                        }
+                        block[scan[ccoef]] = t;
+                    }
+                }
+                break;
+            case 1:
+                mode_list[list_pos] = (ccoef << 2) | 2;
+                for (i = 0; i < 3; i++) {
+                    ccoef += 4;
+                    mode_list[list_end++] = (ccoef << 2) | 2;
+                }
+                break;
+            case 3:
+                if (!bits) {
+                    t = get_bits1(gb) ? -1 : 1;
+                } else {
+                    t = get_bits(gb, bits) | mask;
+                    if (get_bits1(gb))
+                        t = -t;
+                }
+                block[scan[ccoef]] = t;
+                mode_list[list_pos++] = 0;
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+/**
+ * Reads 8x8 block with residue after motion compensation.
+ *
+ * @param gb          context for reading bits
+ * @param block       place to store read data
+ * @param masks_count number of masks to decode
+ * @return 0 on success, negative value in other cases
+ */
+static int read_residue(GetBitContext *gb, DCTELEM block[64], int masks_count)
+{
+    int mode_list[128];
+    int i, mask, ccoef, mode;
+    int list_start = 64, list_end = 64, list_pos;
+    int nz_coeff[64];
+    int nz_coeff_count = 0;
+
+    mode_list[list_end++] = ( 4 << 2) | 0;
+    mode_list[list_end++] = (24 << 2) | 0;
+    mode_list[list_end++] = (44 << 2) | 0;
+    mode_list[list_end++] = ( 0 << 2) | 2;
+
+    for (mask = 1 << get_bits(gb, 3); mask; mask >>= 1) {
+        for (i = 0; i < nz_coeff_count; i++) {
+            if (!get_bits1(gb))
+                continue;
+            if (block[nz_coeff[i]] < 0)
+                block[nz_coeff[i]] -= mask;
+            else
+                block[nz_coeff[i]] += mask;
+            masks_count--;
+            if (masks_count < 0)
+                return 0;
+        }
+        list_pos = list_start;
+        while (list_pos < list_end) {
+            if (!mode_list[list_pos] || !get_bits1(gb)) {
+                list_pos++;
+                continue;
+            }
+            ccoef = mode_list[list_pos] >> 2;
+            mode  = mode_list[list_pos] & 3;
+            switch (mode) {
+            case 0:
+            case 2:
+                if (!mode) {
+                    mode_list[list_pos] = ((ccoef + 4) << 2) | 1;
+                } else {
+                    mode_list[list_pos++] = 0;
+                }
+                for (i = 0; i < 4; i++, ccoef++) {
+                    if (get_bits1(gb)) {
+                        mode_list[--list_start] = (ccoef << 2) | 3;
+                    } else {
+                        nz_coeff[nz_coeff_count++] = bink_scan[ccoef];
+                        block[bink_scan[ccoef]] = get_bits1(gb) ? -mask : mask;
+                        masks_count--;
+                        if (masks_count < 0)
+                            return 0;
+                    }
+                }
+                break;
+            case 1:
+                mode_list[list_pos] = (ccoef << 2) | 2;
+                for (i = 0; i < 3; i++) {
+                    ccoef += 4;
+                    mode_list[list_end++] = (ccoef << 2) | 2;
+                }
+                break;
+            case 3:
+                nz_coeff[nz_coeff_count++] = bink_scan[ccoef];
+                block[bink_scan[ccoef]] = get_bits1(gb) ? -mask : mask;
+                mode_list[list_pos++] = 0;
+                masks_count--;
+                if (masks_count < 0)
+                    return 0;
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+#define PUT2x2(dst, stride, x, y, pix) \
+    dst[(x)*2 +     (y)*2       * stride] = \
+    dst[(x)*2 + 1 + (y)*2       * stride] = \
+    dst[(x)*2 +     ((y)*2 + 1) * stride] = \
+    dst[(x)*2 + 1 + ((y)*2 + 1) * stride] = pix;
+
+static inline void copy_block(BinkContext * const c, DCTELEM block[64],
+                              const uint8_t *src, uint8_t *dst, int stride)
+{
+    c->dsp.get_pixels(block, src, stride);
+    c->dsp.put_pixels_clamped(block, dst, stride);
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)
+{
+    BinkContext * const c = avctx->priv_data;
+    GetBitContext gb;
+    int blk, bw, bh;
+    int i, j, p, nplanes, bx, by;
+    uint8_t *dst, *prev;
+    int v, c1, c2;
+    const uint8_t *scan;
+    const uint32_t *quant;
+    int xoff, yoff;
+    DECLARE_ALIGNED_16(DCTELEM, block[64]);
+
+    if(c->pic.data[0])
+        avctx->release_buffer(avctx, &c->pic);
+
+    if(avctx->get_buffer(avctx, &c->pic) < 0){
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return -1;
+    }
+
+    init_get_bits(&gb, pkt->data, pkt->size*8);
+    if (c->version >= 'i')
+        skip_bits_long(&gb, 32);
+
+    nplanes = (c->flags & BINK_GRAYSCALE) ? 1 : 3;
+
+    for (p = 0; p < nplanes; p++) {
+        const int plane = (p > 0 && c->version > 'g') ? p ^ 3 : p;
+        const int stride = c->pic.linesize[plane];
+
+        bw = plane ? (avctx->width  + 15) >> 4 : (avctx->width  + 7) >> 3;
+        bh = plane ? (avctx->height + 15) >> 4 : (avctx->height + 7) >> 3;
+        init_lengths(c, avctx->width >> !!plane, bw);
+        for (i = 0; i < BINK_NB_SRC; i++)
+            read_bundle(&gb, c, i);
+
+        for (by = 0; by < bh; by++) {
+            if (read_block_types(&gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0)
+                return -1;
+            if (read_block_types(&gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0)
+                return -1;
+            if (read_colors(&gb, &c->bundle[BINK_SRC_COLORS], c) < 0)
+                return -1;
+            if (read_patterns(&gb, &c->bundle[BINK_SRC_PATTERN]) < 0)
+                return -1;
+            if (read_motion_values(&gb, &c->bundle[BINK_SRC_X_OFF]) < 0)
+                return -1;
+            if (read_motion_values(&gb, &c->bundle[BINK_SRC_Y_OFF]) < 0)
+                return -1;
+            if (read_dcs(&gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0)
+                return -1;
+            if (read_dcs(&gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0)
+                return -1;
+            if (read_runs(&gb, &c->bundle[BINK_SRC_RUN]) < 0)
+                return -1;
+
+            if (by == bh)
+                break;
+            dst = c->pic.data[plane] + 8*by*stride;
+            prev = c->last.data[plane] + 8*by*stride;
+            for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) {
+                blk = get_value(c, BINK_SRC_BLOCK_TYPES);
+                if ((by & 1) && blk == 1) {
+                    bx++;
+                    dst  += 8;
+                    prev += 8;
+                    continue;
+                }
+                switch (blk) {
+                case SKIP_BLOCK:
+                    copy_block(c, block, prev, dst, stride);
+                    break;
+                case SCALED_BLOCK:
+                    blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES);
+                    switch (blk) {
+                    case RUN_BLOCK:
+                        scan = bink_patterns[get_bits(&gb, 4)];
+                        i = 0;
+                        do {
+                            int run = get_value(c, BINK_SRC_RUN) + 1;
+                            if (get_bits1(&gb)) {
+                                v = get_value(c, BINK_SRC_COLORS);
+                                for (j = 0; j < run; j++) {
+                                    int pos = *scan++;
+                                    PUT2x2(dst, stride, pos & 7, pos >> 3, v);
+                                }
+                            } else {
+                                for (j = 0; j < run; j++) {
+                                    int pos = *scan++;
+                                    PUT2x2(dst, stride, pos & 7, pos >> 3, get_value(c, BINK_SRC_COLORS));
+                                }
+                            }
+                            i += run;
+                        } while (i < 63);
+                        if (i == 63) {
+                            int pos = *scan++;
+                            PUT2x2(dst, stride, pos & 7, pos >> 3, get_value(c, BINK_SRC_COLORS));
+                        }
+                        break;
+                    case INTRA_BLOCK:
+                        c->dsp.clear_block(block);
+                        block[0] = get_value(c, BINK_SRC_INTRA_DC);
+                        read_dct_coeffs(&gb, block, c->scantable.permutated);
+                        quant = bink_intra_quant[get_bits(&gb, 4)];
+                        for (i = 0; i < 64; i++)
+                            block[i] = MUL64(block[i], quant[i]) >> 16;
+                        c->dsp.idct(block);
+                        for (j = 0; j < 8; j++)
+                            for (i = 0; i < 8; i++)
+                                PUT2x2(dst, stride, i, j, block[i + j*8]);
+                        break;
+                    case FILL_BLOCK:
+                        v = get_value(c, BINK_SRC_COLORS);
+                        for (j = 0; j < 16; j++)
+                            memset(dst + j*stride, v, 16);
+                        break;
+                    case PATTERN_BLOCK:
+                        c1 = get_value(c, BINK_SRC_COLORS);
+                        c2 = get_value(c, BINK_SRC_COLORS);
+                        for (i = 0; i < 8; i++) {
+                            v = get_value(c, BINK_SRC_PATTERN);
+                            for (j = 0; j < 8; j++, v >>= 1)
+                                PUT2x2(dst, stride, i, j, (v & 1) ? c2 : c1);
+                        }
+                        break;
+                    case RAW_BLOCK:
+                        for (j = 0; j < 8; j++)
+                            for (i = 0; i < 8; i++)
+                                PUT2x2(dst, stride, i, j, get_value(c, BINK_SRC_COLORS));
+                        break;
+                    default:
+                        av_log(avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk);
+                        return -1;
+                    }
+                    bx++;
+                    dst += 8;
+                    prev += 8;
+                    break;
+                case MOTION_BLOCK:
+                    xoff = get_value(c, BINK_SRC_X_OFF);
+                    yoff = get_value(c, BINK_SRC_Y_OFF);
+                    copy_block(c, block, prev + xoff + yoff*stride, dst, stride);
+                    break;
+                case RUN_BLOCK:
+                    scan = bink_patterns[get_bits(&gb, 4)];
+                    i = 0;
+                    do {
+                        int run = get_value(c, BINK_SRC_RUN) + 1;
+                        if (get_bits1(&gb)) {
+                            v = get_value(c, BINK_SRC_COLORS);
+                            for (j = 0; j < run; j++) {
+                                int pos = *scan++;
+                                dst[(pos & 7) + (pos >> 3) * stride] = v;
+                            }
+                        } else {
+                            for (j = 0; j < run; j++) {
+                                int pos = *scan++;
+                                dst[(pos & 7) + (pos >> 3) * stride] = get_value(c, BINK_SRC_COLORS);
+                            }
+                        }
+                        i += run;
+                    } while (i < 63);
+                    if (i == 63) {
+                        int pos = *scan++;
+                        dst[(pos & 7) + (pos >> 3)*stride] = get_value(c, BINK_SRC_COLORS);
+                    }
+                    break;
+                case RESIDUE_BLOCK:
+                    xoff = get_value(c, BINK_SRC_X_OFF);
+                    yoff = get_value(c, BINK_SRC_Y_OFF);
+                    copy_block(c, block, prev + xoff + yoff*stride, dst, stride);
+                    c->dsp.clear_block(block);
+                    v = get_bits(&gb, 7);
+                    read_residue(&gb, block, v);
+                    c->dsp.add_pixels_clamped(block, dst, stride);
+                    break;
+                case INTRA_BLOCK:
+                    c->dsp.clear_block(block);
+                    block[0] = get_value(c, BINK_SRC_INTRA_DC);
+                    read_dct_coeffs(&gb, block, c->scantable.permutated);
+                    quant = bink_intra_quant[get_bits(&gb, 4)];
+                    for (i = 0; i < 64; i++)
+                        block[i] = MUL64(block[i], quant[i]) >> 16;
+                    c->dsp.idct_put(dst, stride, block);
+                    break;
+                case FILL_BLOCK:
+                    v = get_value(c, BINK_SRC_COLORS);
+                    for (i = 0; i < 8; i++)
+                        memset(dst + i*stride, v, 8);
+                    break;
+                case INTER_BLOCK:
+                    xoff = get_value(c, BINK_SRC_X_OFF);
+                    yoff = get_value(c, BINK_SRC_Y_OFF);
+                    copy_block(c, block, prev + xoff + yoff*stride, dst, stride);
+                    c->dsp.clear_block(block);
+                    block[0] = get_value(c, BINK_SRC_INTER_DC);
+                    read_dct_coeffs(&gb, block, c->scantable.permutated);
+                    quant = bink_inter_quant[get_bits(&gb, 4)];
+                    for (i = 0; i < 64; i++)
+                        block[i] = MUL64(block[i], quant[i]) >> 16;
+                    c->dsp.idct_add(dst, stride, block);
+                    break;
+                case PATTERN_BLOCK:
+                    c1 = get_value(c, BINK_SRC_COLORS);
+                    c2 = get_value(c, BINK_SRC_COLORS);
+                    for (i = 0; i < 8; i++) {
+                        v = get_value(c, BINK_SRC_PATTERN);
+                        for (j = 0; j < 8; j++, v >>= 1)
+                            dst[i + j*stride] = (v & 1) ? c2 : c1;
+                    }
+                    break;
+                case RAW_BLOCK:
+                    for (i = 0; i < 8; i++)
+                        memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8);
+                    c->bundle[BINK_SRC_COLORS].cur_ptr += 64;
+                    break;
+                default:
+                    av_log(avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk);
+                    return -1;
+                }
+            }
+        }
+        if (get_bits_count(&gb) & 0x1F) //next plane data starts at 32-bit boundary
+            skip_bits_long(&gb, 32 - (get_bits_count(&gb) & 0x1F));
+    }
+    emms_c();
+
+    *data_size = sizeof(AVFrame);
+    *(AVFrame*)data = c->pic;
+
+    FFSWAP(AVFrame, c->pic, c->last);
+
+    /* always report that the buffer was completely consumed */
+    return pkt->size;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+    BinkContext * const c = avctx->priv_data;
+    static VLC_TYPE table[16 * 128][2];
+    int i;
+
+    c->version = avctx->codec_tag >> 24;
+    if (avctx->extradata_size >= 4)
+        c->flags = AV_RL32(avctx->extradata);
+    if (!bink_trees[15].table) {
+        for (i = 0; i < 16; i++) {
+            const int maxbits = bink_tree_lens[i][15];
+            bink_trees[i].table = table + i*128;
+            bink_trees[i].table_allocated = 1 << maxbits;
+            init_vlc(&bink_trees[i], maxbits, 16,
+                     bink_tree_lens[i], 1, 1,
+                     bink_tree_bits[i], 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
+        }
+    }
+    c->avctx = avctx;
+
+    c->pic.data[0] = NULL;
+
+    if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
+        return 1;
+    }
+
+    avctx->pix_fmt = PIX_FMT_YUV420P;
+
+    dsputil_init(&c->dsp, avctx);
+    ff_init_scantable(c->dsp.idct_permutation, &c->scantable, bink_scan);
+
+    init_bundles(c);
+
+    return 0;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+    BinkContext * const c = avctx->priv_data;
+
+    if (c->pic.data[0])
+        avctx->release_buffer(avctx, &c->pic);
+    if (c->last.data[0])
+        avctx->release_buffer(avctx, &c->last);
+
+    free_bundles(c);
+    return 0;
+}
+
+AVCodec bink_decoder = {
+    "binkvid",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_BINKVIDEO,
+    sizeof(BinkContext),
+    decode_init,
+    NULL,
+    decode_end,
+    decode_frame,
+    .long_name = NULL_IF_CONFIG_SMALL("Bink video"),
+};
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
new file mode 100644
index 0000000..b854466
--- /dev/null
+++ b/libavcodec/binkaudio.c
@@ -0,0 +1,307 @@
+/*
+ * Bink Audio decoder
+ * Copyright (c) 2007-2009 Peter Ross (pross at xvid.org)
+ * Copyright (c) 2009 Daniel Verkamp (daniel at drv.nu)
+ *
+ * This file is part of FFmpeg.
+ *
+ * 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.
+ *
+ * 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
+ */
+
+/**
+ * @file libavcodec/binkaudio.c
+ *
+ * Technical details here:
+ *  http://wiki.multimedia.cx/index.php?title=Bink_Audio
+ */
+
+#include "avcodec.h"
+#define ALT_BITSTREAM_READER_LE
+#include "get_bits.h"
+#include "dsputil.h"
+extern const uint16_t ff_wma_critical_freqs[25];
+
+#define MAX_CHANNELS 2
+#define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11)
+
+typedef struct {
+    AVCodecContext *avctx;
+    GetBitContext gb;
+    DSPContext dsp;
+    int use_dct;
+    int first;
+    int channels;
+    int frame_len;          ///< transform size (samples)
+    int overlap_len;        ///< overlap size (samples)
+    int block_size;
+    int num_bands;
+    unsigned int *bands;
+    float root;
+    DECLARE_ALIGNED_16(FFTSample, coeffs[BINK_BLOCK_MAX_SIZE]);
+    DECLARE_ALIGNED_16(short, previous[BINK_BLOCK_MAX_SIZE / 16]);  ///< coeffs from previous audio block
+    float *coeffs_ptr[MAX_CHANNELS]; ///< pointers to the coeffs arrays for float_to_int16_interleave
+    union {
+        RDFTContext rdft;
+        DCTContext dct;
+    } trans;
+} BinkAudioContext;
+
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+    BinkAudioContext *s = avctx->priv_data;
+    int sample_rate = avctx->sample_rate;
+    int sample_rate_half;
+    int i;
+    int frame_len_bits;
+
+    s->avctx = avctx;
+    dsputil_init(&s->dsp, avctx);
+
+    /* determine frame length */
+    if (avctx->sample_rate < 22050) {
+        frame_len_bits = 9;
+    } else if (avctx->sample_rate < 44100) {
+        frame_len_bits = 10;
+    } else {
+        frame_len_bits = 11;
+    }
+    s->frame_len = 1 << frame_len_bits;
+
+    if (s->channels > MAX_CHANNELS) {
+        av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
+        return -1;
+    }
+
+    s->use_dct = (avctx->codec->id == CODEC_ID_BINKAUDIO2);
+
+    if (s->use_dct) {
+        s->channels = avctx->channels;
+    } else {
+        // audio is already interleaved for the RDFT format variant
+        sample_rate  *= avctx->channels;
+        s->frame_len *= avctx->channels;
+        s->channels = 1;
+        if (avctx->channels == 2)
+            frame_len_bits++;
+    }
+
+    s->overlap_len   = s->frame_len / 16;
+    s->block_size    = (s->frame_len - s->overlap_len) * s->channels;
+    sample_rate_half = (sample_rate + 1) / 2;
+    s->root          = 2.0 / sqrt(s->frame_len);
+
+    /* calculate number of bands */
+    for (s->num_bands = 1; s->num_bands < 25; s->num_bands++)
+        if (sample_rate_half <= ff_wma_critical_freqs[s->num_bands - 1])
+            break;
+
+    s->bands = av_malloc((s->num_bands + 1) * sizeof(*s->bands));
+    if (!s->bands)
+        return AVERROR(ENOMEM);
+
+    /* populate bands data */
+    s->bands[0] = 1;
+    for (i = 1; i < s->num_bands; i++)
+        s->bands[i] = ff_wma_critical_freqs[i - 1] * (s->frame_len / 2) / sample_rate_half;
+    s->bands[s->num_bands] = s->frame_len / 2;
+
+    s->first = 1;
+    avctx->sample_fmt = SAMPLE_FMT_S16;
+
+    for (i = 0; i < s->channels; i++)
+        s->coeffs_ptr[i] = s->coeffs + i * s->frame_len;
+
+    if (s->use_dct)
+        ff_dct_init(&s->trans.dct, frame_len_bits, 0);
+    else
+        ff_rdft_init(&s->trans.rdft, frame_len_bits, IRIDFT);
+
+    return 0;
+}
+
+static float get_float(GetBitContext *gb)
+{
+    int power = get_bits(gb, 5);
+    float f = ldexpf(get_bits_long(gb, 23), power - 23);
+    if (get_bits1(gb))
+        f = -f;
+    return f;
+}
+
+static const uint8_t rle_length_tab[16] = {
+    2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64
+};
+
+/**
+ * Decode Bink Audio block
+ * @param[out] out Output buffer (must contain s->block_size elements)
+ */
+static void decode_block(BinkAudioContext *s, short *out)
+{
+    int ch, i, j, k;
+    float q, quant[25];
+    int width, coeff;
+    GetBitContext *gb = &s->gb;
+
+    if (s->use_dct) {
+        skip_bits(gb, 2);
+    }
+
+    for (ch = 0; ch < s->channels; ch++) {
+        FFTSample *coeffs = s->coeffs_ptr[ch];
+        q = 0.0;
+        coeffs[0] = get_float(gb);
+        coeffs[1] = get_float(gb);
+
+        for (i = 0; i < s->num_bands; i++) {
+            int value = get_bits(gb, 8);
+            quant[i] = pow(10.0, FFMIN(value, 95) * 0.066399999);
+        }
+
+        // find band (k)
+        for (k = 0; s->bands[k] * 2 < 2; k++) {
+            q = quant[k];
+        }
+
+        // parse coefficients
+        i = 2;
+        while (i < s->frame_len) {
+            if (get_bits1(gb)) {
+                j = i + rle_length_tab[get_bits(gb, 4)] * 8;
+            } else {
+                j = i + 8;
+            }
+
+            if (j > s->frame_len)
+                j = s->frame_len;
+
+            width = get_bits(gb, 4);
+            if (width == 0) {
+                memset(coeffs + i, 0, (j - i) * sizeof(*coeffs));
+                i = j;
+                while (s->bands[k] * 2 < i)
+                    q = quant[k++];
+            } else {
+                while (i < j) {
+                    if (s->bands[k] * 2 == i)
+                        q = quant[k++];
+                    coeff = get_bits(gb, width);
+                    if (coeff) {
+                        if (get_bits1(gb))
+                            coeffs[i] = -q * coeff;
+                        else
+                            coeffs[i] =  q * coeff;
+                    } else {
+                        coeffs[i] = 0.0;
+                    }
+                    i++;
+                }
+            }
+        }
+
+        if (s->use_dct)
+            ff_dct_calc (&s->trans.dct,  coeffs);
+        else
+            ff_rdft_calc(&s->trans.rdft, coeffs);
+
+        for (i = 0; i < s->frame_len; i++)
+            coeffs[i] *= s->root;
+    }
+
+    s->dsp.float_to_int16_interleave(out, (const float **)s->coeffs_ptr, s->frame_len, s->channels);
+
+    if (!s->first) {
+        int count = s->overlap_len * s->channels;
+        int shift = av_log2(count);
+        for (i = 0; i < count; i++) {
+            out[i] = (s->previous[i] * (count - i) + out[i] * i) >> shift;
+        }
+    }
+
+    memcpy(s->previous, out + s->block_size,
+           s->overlap_len * s->channels * sizeof(*out));
+
+    s->first = 0;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+    BinkAudioContext * s = avctx->priv_data;
+    av_free(s->bands);
+    if (s->use_dct)
+        ff_dct_end(&s->trans.dct);
+    else
+        ff_rdft_end(&s->trans.rdft);
+    return 0;
+}
+
+static void get_bits_align32(GetBitContext *s)
+{
+    int n = (-get_bits_count(s)) & 31;
+    if (n) skip_bits(s, n);
+}
+
+static int decode_frame(AVCodecContext *avctx,
+                        void *data, int *data_size,
+                        AVPacket *avpkt)
+{
+    BinkAudioContext *s = avctx->priv_data;
+    const uint8_t *buf  = avpkt->data;
+    int buf_size        = avpkt->size;
+    short *samples      = data;
+    short *samples_end  = (void*)((uint8_t*)data + *data_size);
+    int reported_size;
+    GetBitContext *gb = &s->gb;
+
+    init_get_bits(gb, buf, buf_size * 8);
+
+    reported_size = get_bits_long(gb, 32);
+    while (get_bits_count(gb) / 8 < buf_size &&
+           samples + s->block_size <= samples_end) {
+        decode_block(s, samples);
+        samples += s->block_size;
+        get_bits_align32(gb);
+    }
+
+    *data_size = (uint8_t*)samples - (uint8_t*)data;
+    if (reported_size != *data_size) {
+        av_log(avctx, AV_LOG_WARNING, "reported data size (%d) does not match output data size (%d)\n",
+             reported_size, *data_size);
+    }
+    return buf_size;
+}
+
+AVCodec binkaudio1_decoder = {
+    "binkaudio1",
+    CODEC_TYPE_AUDIO,
+    CODEC_ID_BINKAUDIO1,
+    sizeof(BinkAudioContext),
+    decode_init,
+    NULL,
+    decode_end,
+    decode_frame
+};
+
+AVCodec binkaudio2_decoder = {
+    "binkaudio2",
+    CODEC_TYPE_AUDIO,
+    CODEC_ID_BINKAUDIO2,
+    sizeof(BinkAudioContext),
+    decode_init,
+    NULL,
+    decode_end,
+    decode_frame
+};
diff --git a/libavcodec/binkdata.h b/libavcodec/binkdata.h
new file mode 100644
index 0000000..9844008
--- /dev/null
+++ b/libavcodec/binkdata.h
@@ -0,0 +1,612 @@
+/*
+ * Bink video decoder
+ * Copyright (C) 2009 Kostya Shishkov
+ *
+ * This file is part of FFmpeg.
+ *
+ * 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.
+ *
+ * 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
+ */
+
+#ifndef AVCODEC_BINKDATA_H
+#define AVCODEC_BINKDATA_H
+
+/** Bink DCT and residue 8x8 block scan order */
+static const uint8_t bink_scan[64] = {
+     0,  1,  8,  9,  2,  3, 10, 11,
+     4,  5, 12, 13,  6,  7, 14, 15,
+    20, 21, 28, 29, 22, 23, 30, 31,
+    16, 17, 24, 25, 32, 33, 40, 41,
+    34, 35, 42, 43, 48, 49, 56, 57,
+    50, 51, 58, 59, 18, 19, 26, 27,
+    36, 37, 44, 45, 38, 39, 46, 47,
+    52, 53, 60, 61, 54, 55, 62, 63
+};
+
+static const uint8_t bink_tree_bits[16][16] = {
+    {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+    },
+    {
+        0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D,
+        0x0F, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,
+    },
+    {
+        0x00, 0x02, 0x01, 0x09, 0x05, 0x15, 0x0D, 0x1D,
+        0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
+    },
+    {
+        0x00, 0x02, 0x06, 0x01, 0x09, 0x05, 0x0D, 0x1D,
+        0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
+    },
+    {
+        0x00, 0x04, 0x02, 0x06, 0x01, 0x09, 0x05, 0x0D,
+        0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
+    },
+    {
+        0x00, 0x04, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09,
+        0x05, 0x0D, 0x03, 0x0B, 0x07, 0x17, 0x0F, 0x1F,
+    },
+    {
+        0x00, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, 0x05,
+        0x0D, 0x03, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
+    },
+    {
+        0x00, 0x01, 0x05, 0x03, 0x13, 0x0B, 0x1B, 0x3B,
+        0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
+    },
+    {
+        0x00, 0x01, 0x03, 0x13, 0x0B, 0x2B, 0x1B, 0x3B,
+        0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
+    },
+    {
+        0x00, 0x01, 0x05, 0x0D, 0x03, 0x13, 0x0B, 0x1B,
+        0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
+    },
+    {
+        0x00, 0x02, 0x01, 0x05, 0x0D, 0x03, 0x13, 0x0B,
+        0x1B, 0x07, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
+    },
+    {
+        0x00, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x13, 0x0B,
+        0x1B, 0x07, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
+    },
+    {
+        0x00, 0x02, 0x01, 0x03, 0x13, 0x0B, 0x1B, 0x3B,
+        0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
+    },
+    {
+        0x00, 0x01, 0x05, 0x03, 0x07, 0x27, 0x17, 0x37,
+        0x0F, 0x4F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F,
+    },
+    {
+        0x00, 0x01, 0x05, 0x03, 0x07, 0x17, 0x37, 0x77,
+        0x0F, 0x4F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F,
+    },
+    {
+        0x00, 0x02, 0x01, 0x05, 0x03, 0x07, 0x27, 0x17,
+        0x37, 0x0F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F,
+    },
+};
+
+static const uint8_t bink_tree_lens[16][16] = {
+    { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
+    { 1, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
+    { 2, 2, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
+    { 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
+    { 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 },
+    { 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5 },
+    { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5 },
+    { 1, 3, 3, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
+    { 1, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
+    { 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6 },
+    { 2, 2, 3, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 },
+    { 1, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 },
+    { 2, 2, 2, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
+    { 1, 3, 3, 3, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7 },
+    { 1, 3, 3, 3, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 },
+    { 2, 2, 3, 3, 3, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7 },
+};
+
+static const uint8_t bink_patterns[16][64] = {
+    {
+        0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38,
+        0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09, 0x01,
+        0x02, 0x0A, 0x12, 0x1A, 0x22, 0x2A, 0x32, 0x3A,
+        0x3B, 0x33, 0x2B, 0x23, 0x1B, 0x13, 0x0B, 0x03,
+        0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34, 0x3C,
+        0x3D, 0x35, 0x2D, 0x25, 0x1D, 0x15, 0x0D, 0x05,
+        0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, 0x36, 0x3E,
+        0x3F, 0x37, 0x2F, 0x27, 0x1F, 0x17, 0x0F, 0x07,
+    },
+    {
+        0x3B, 0x3A, 0x39, 0x38, 0x30, 0x31, 0x32, 0x33,
+        0x2B, 0x2A, 0x29, 0x28, 0x20, 0x21, 0x22, 0x23,
+        0x1B, 0x1A, 0x19, 0x18, 0x10, 0x11, 0x12, 0x13,
+        0x0B, 0x0A, 0x09, 0x08, 0x00, 0x01, 0x02, 0x03,
+        0x04, 0x05, 0x06, 0x07, 0x0F, 0x0E, 0x0D, 0x0C,
+        0x14, 0x15, 0x16, 0x17, 0x1F, 0x1E, 0x1D, 0x1C,
+        0x24, 0x25, 0x26, 0x27, 0x2F, 0x2E, 0x2D, 0x2C,
+        0x34, 0x35, 0x36, 0x37, 0x3F, 0x3E, 0x3D, 0x3C,
+    },
+    {
+        0x19, 0x11, 0x12, 0x1A, 0x1B, 0x13, 0x0B, 0x03,
+        0x02, 0x0A, 0x09, 0x01, 0x00, 0x08, 0x10, 0x18,
+        0x20, 0x28, 0x30, 0x38, 0x39, 0x31, 0x29, 0x2A,
+        0x32, 0x3A, 0x3B, 0x33, 0x2B, 0x23, 0x22, 0x21,
+        0x1D, 0x15, 0x16, 0x1E, 0x1F, 0x17, 0x0F, 0x07,
+        0x06, 0x0E, 0x0D, 0x05, 0x04, 0x0C, 0x14, 0x1C,
+        0x24, 0x2C, 0x34, 0x3C, 0x3D, 0x35, 0x2D, 0x2E,
+        0x36, 0x3E, 0x3F, 0x37, 0x2F, 0x27, 0x26, 0x25,
+    },
+    {
+        0x03, 0x0B, 0x02, 0x0A, 0x01, 0x09, 0x00, 0x08,
+        0x10, 0x18, 0x11, 0x19, 0x12, 0x1A, 0x13, 0x1B,
+        0x23, 0x2B, 0x22, 0x2A, 0x21, 0x29, 0x20, 0x28,
+        0x30, 0x38, 0x31, 0x39, 0x32, 0x3A, 0x33, 0x3B,
+        0x3C, 0x34, 0x3D, 0x35, 0x3E, 0x36, 0x3F, 0x37,
+        0x2F, 0x27, 0x2E, 0x26, 0x2D, 0x25, 0x2C, 0x24,
+        0x1C, 0x14, 0x1D, 0x15, 0x1E, 0x16, 0x1F, 0x17,
+        0x0F, 0x07, 0x0E, 0x06, 0x0D, 0x05, 0x0C, 0x04,
+    },
+    {
+        0x18, 0x19, 0x10, 0x11, 0x08, 0x09, 0x00, 0x01,
+        0x02, 0x03, 0x0A, 0x0B, 0x12, 0x13, 0x1A, 0x1B,
+        0x1C, 0x1D, 0x14, 0x15, 0x0C, 0x0D, 0x04, 0x05,
+        0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F,
+        0x27, 0x26, 0x2F, 0x2E, 0x37, 0x36, 0x3F, 0x3E,
+        0x3D, 0x3C, 0x35, 0x34, 0x2D, 0x2C, 0x25, 0x24,
+        0x23, 0x22, 0x2B, 0x2A, 0x33, 0x32, 0x3B, 0x3A,
+        0x39, 0x38, 0x31, 0x30, 0x29, 0x28, 0x21, 0x20,
+    },
+    {
+        0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B,
+        0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B,
+        0x20, 0x21, 0x22, 0x23, 0x28, 0x29, 0x2A, 0x2B,
+        0x30, 0x31, 0x32, 0x33, 0x38, 0x39, 0x3A, 0x3B,
+        0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F,
+        0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F,
+        0x24, 0x25, 0x26, 0x27, 0x2C, 0x2D, 0x2E, 0x2F,
+        0x34, 0x35, 0x36, 0x37, 0x3C, 0x3D, 0x3E, 0x3F,
+    },
+    {
+        0x06, 0x07, 0x0F, 0x0E, 0x0D, 0x05, 0x0C, 0x04,
+        0x03, 0x0B, 0x02, 0x0A, 0x09, 0x01, 0x00, 0x08,
+        0x10, 0x18, 0x11, 0x19, 0x12, 0x1A, 0x13, 0x1B,
+        0x14, 0x1C, 0x15, 0x1D, 0x16, 0x1E, 0x17, 0x1F,
+        0x27, 0x2F, 0x26, 0x2E, 0x25, 0x2D, 0x24, 0x2C,
+        0x23, 0x2B, 0x22, 0x2A, 0x21, 0x29, 0x20, 0x28,
+        0x31, 0x30, 0x38, 0x39, 0x3A, 0x32, 0x3B, 0x33,
+        0x3C, 0x34, 0x3D, 0x35, 0x36, 0x37, 0x3F, 0x3E,
+    },
+    {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
+        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+        0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+        0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38,
+    },
+    {
+        0x00, 0x08, 0x09, 0x01, 0x02, 0x03, 0x0B, 0x0A,
+        0x12, 0x13, 0x1B, 0x1A, 0x19, 0x11, 0x10, 0x18,
+        0x20, 0x28, 0x29, 0x21, 0x22, 0x23, 0x2B, 0x2A,
+        0x32, 0x31, 0x30, 0x38, 0x39, 0x3A, 0x3B, 0x33,
+        0x34, 0x3C, 0x3D, 0x3E, 0x3F, 0x37, 0x36, 0x35,
+        0x2D, 0x2C, 0x24, 0x25, 0x26, 0x2E, 0x2F, 0x27,
+        0x1F, 0x17, 0x16, 0x1E, 0x1D, 0x1C, 0x14, 0x15,
+        0x0D, 0x0C, 0x04, 0x05, 0x06, 0x0E, 0x0F, 0x07,
+    },
+    {
+        0x18, 0x19, 0x10, 0x11, 0x08, 0x09, 0x00, 0x01,
+        0x02, 0x03, 0x0A, 0x0B, 0x12, 0x13, 0x1A, 0x1B,
+        0x1C, 0x1D, 0x14, 0x15, 0x0C, 0x0D, 0x04, 0x05,
+        0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F,
+        0x26, 0x27, 0x2E, 0x2F, 0x36, 0x37, 0x3E, 0x3F,
+        0x3C, 0x3D, 0x34, 0x35, 0x2C, 0x2D, 0x24, 0x25,
+        0x22, 0x23, 0x2A, 0x2B, 0x32, 0x33, 0x3A, 0x3B,
+        0x38, 0x39, 0x30, 0x31, 0x28, 0x29, 0x20, 0x21,
+    },
+    {
+        0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B,
+        0x13, 0x1B, 0x12, 0x1A, 0x11, 0x19, 0x10, 0x18,
+        0x20, 0x28, 0x21, 0x29, 0x22, 0x2A, 0x23, 0x2B,
+        0x33, 0x3B, 0x32, 0x3A, 0x31, 0x39, 0x30, 0x38,
+        0x3C, 0x34, 0x3D, 0x35, 0x3E, 0x36, 0x3F, 0x37,
+        0x2F, 0x27, 0x2E, 0x26, 0x2D, 0x25, 0x2C, 0x24,
+        0x1F, 0x17, 0x1E, 0x16, 0x1D, 0x15, 0x1C, 0x14,
+        0x0C, 0x04, 0x0D, 0x05, 0x0E, 0x06, 0x0F, 0x07,
+    },
+    {
+        0x00, 0x08, 0x10, 0x18, 0x19, 0x1A, 0x1B, 0x13,
+        0x0B, 0x03, 0x02, 0x01, 0x09, 0x11, 0x12, 0x0A,
+        0x04, 0x0C, 0x14, 0x1C, 0x1D, 0x1E, 0x1F, 0x17,
+        0x0F, 0x07, 0x06, 0x05, 0x0D, 0x15, 0x16, 0x0E,
+        0x24, 0x2C, 0x34, 0x3C, 0x3D, 0x3E, 0x3F, 0x37,
+        0x2F, 0x27, 0x26, 0x25, 0x2D, 0x35, 0x36, 0x2E,
+        0x20, 0x28, 0x30, 0x38, 0x39, 0x3A, 0x3B, 0x33,
+        0x2B, 0x23, 0x22, 0x21, 0x29, 0x31, 0x32, 0x2A,
+    },
+    {
+        0x00, 0x08, 0x09, 0x01, 0x02, 0x03, 0x0B, 0x0A,
+        0x13, 0x1B, 0x1A, 0x12, 0x11, 0x10, 0x18, 0x19,
+        0x21, 0x20, 0x28, 0x29, 0x2A, 0x22, 0x23, 0x2B,
+        0x33, 0x3B, 0x3A, 0x32, 0x31, 0x39, 0x38, 0x30,
+        0x34, 0x3C, 0x3D, 0x35, 0x36, 0x3E, 0x3F, 0x37,
+        0x2F, 0x27, 0x26, 0x2E, 0x2D, 0x2C, 0x24, 0x25,
+        0x1D, 0x1C, 0x14, 0x15, 0x16, 0x1E, 0x1F, 0x17,
+        0x0E, 0x0F, 0x07, 0x06, 0x05, 0x0D, 0x0C, 0x04,
+    },
+    {
+        0x18, 0x10, 0x08, 0x00, 0x01, 0x02, 0x03, 0x0B,
+        0x13, 0x1B, 0x1A, 0x19, 0x11, 0x0A, 0x09, 0x12,
+        0x1C, 0x14, 0x0C, 0x04, 0x05, 0x06, 0x07, 0x0F,
+        0x17, 0x1F, 0x1E, 0x1D, 0x15, 0x0E, 0x0D, 0x16,
+        0x3C, 0x34, 0x2C, 0x24, 0x25, 0x26, 0x27, 0x2F,
+        0x37, 0x3F, 0x3E, 0x3D, 0x35, 0x2E, 0x2D, 0x36,
+        0x38, 0x30, 0x28, 0x20, 0x21, 0x22, 0x23, 0x2B,
+        0x33, 0x3B, 0x3A, 0x39, 0x31, 0x2A, 0x29, 0x32,
+    },
+    {
+        0x00, 0x08, 0x09, 0x01, 0x02, 0x0A, 0x12, 0x11,
+        0x10, 0x18, 0x19, 0x1A, 0x1B, 0x13, 0x0B, 0x03,
+        0x07, 0x06, 0x0E, 0x0F, 0x17, 0x16, 0x15, 0x0D,
+        0x05, 0x04, 0x0C, 0x14, 0x1C, 0x1D, 0x1E, 0x1F,
+        0x3F, 0x3E, 0x36, 0x37, 0x2F, 0x2E, 0x2D, 0x35,
+        0x3D, 0x3C, 0x34, 0x2C, 0x24, 0x25, 0x26, 0x27,
+        0x38, 0x30, 0x31, 0x39, 0x3A, 0x32, 0x2A, 0x29,
+        0x28, 0x20, 0x21, 0x22, 0x23, 0x2B, 0x33, 0x3B,
+    },
+    {
+        0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19,
+        0x20, 0x21, 0x28, 0x29, 0x30, 0x31, 0x38, 0x39,
+        0x3A, 0x3B, 0x32, 0x33, 0x2A, 0x2B, 0x22, 0x23,
+        0x1A, 0x1B, 0x12, 0x13, 0x0A, 0x0B, 0x02, 0x03,
+        0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
+        0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x3C, 0x3D,
+        0x3E, 0x3F, 0x36, 0x37, 0x2E, 0x2F, 0x26, 0x27,
+        0x1E, 0x1F, 0x16, 0x17, 0x0E, 0x0F, 0x06, 0x07,
+    }
+};
+
+static const uint32_t bink_intra_quant[16][64] = {
+{
+ 0x00010000, 0x00016315, 0x00014E7B, 0x00016577, 0x00010000, 0x0000EEDA, 0x0000BE80, 0x0000611E,
+ 0x0001E83D, 0x0002A535, 0x0002F1E6, 0x0002724C, 0x00024102, 0x00017F9B, 0x0001083C, 0x0000A552,
+ 0x0002346F, 0x00030EE5, 0x0002C628, 0x00027F20, 0x00021F88, 0x0001DC53, 0x00014819, 0x0000A743,
+ 0x0001FBFA, 0x0002C096, 0x000297B5, 0x00023F32, 0x00027FAD, 0x0001F697, 0x00015A31, 0x00009688,
+ 0x0001D000, 0x00028396, 0x0002346F, 0x0001FBFA, 0x00025000, 0x0001AB6B, 0x00012669, 0x00008D43,
+ 0x00019247, 0x0001F9AA, 0x0001DC53, 0x000231B8, 0x0001D122, 0x000159B3, 0x0000EE1F, 0x000075ED,
+ 0x00012F12, 0x0001E06C, 0x0001C48C, 0x00019748, 0x0001490C, 0x00010288, 0x0000E0F1, 0x000072AD,
+ 0x0000CB10, 0x000119A8, 0x00014E86, 0x000122AF, 0x0000F735, 0x0000EF51, 0x0000A4D8, 0x00006517,
+},
+{
+ 0x00015555, 0x0001D971, 0x0001BDF9, 0x0001DC9F, 0x00015555, 0x00013E78, 0x0000FE00, 0x0000817D,
+ 0x00028AFC, 0x000386F1, 0x0003ED33, 0x00034311, 0x00030158, 0x0001FF7A, 0x0001604F, 0x0000DC6D,
+ 0x0002F095, 0x000413DC, 0x0003B2E0, 0x0003542A, 0x0002D4B5, 0x00027B19, 0x0001B577, 0x0000DF04,
+ 0x0002A54E, 0x0003AB73, 0x000374F1, 0x0002FEEE, 0x000354E7, 0x00029E1F, 0x0001CD96, 0x0000C8B6,
+ 0x00026AAB, 0x00035A1E, 0x0002F095, 0x0002A54E, 0x00031555, 0x000239E4, 0x0001888C, 0x0000BC59,
+ 0x0002185E, 0x0002A238, 0x00027B19, 0x0002ECF5, 0x00026C2D, 0x0001CCEE, 0x00013D7E, 0x00009D3C,
+ 0x00019418, 0x00028090, 0x00025B66, 0x00021F0B, 0x0001B6BB, 0x000158B5, 0x00012BEC, 0x000098E6,
+ 0x00010EC0, 0x0001778A, 0x0001BE09, 0x00018394, 0x0001499C, 0x00013F17, 0x0000DBCB, 0x000086C9,
+},
+{
+ 0x0001AAAB, 0x00024FCE, 0x00022D78, 0x000253C7, 0x0001AAAB, 0x00018E16, 0x00013D80, 0x0000A1DC,
+ 0x00032DBB, 0x000468AD, 0x0004E87F, 0x000413D5, 0x0003C1AE, 0x00027F58, 0x0001B863, 0x00011388,
+ 0x0003ACBA, 0x000518D3, 0x00049F98, 0x00042935, 0x000389E2, 0x000319DF, 0x000222D4, 0x000116C5,
+ 0x00034EA1, 0x0004964F, 0x0004522D, 0x0003BEA9, 0x00042A21, 0x000345A7, 0x000240FC, 0x0000FAE3,
+ 0x00030555, 0x000430A5, 0x0003ACBA, 0x00034EA1, 0x0003DAAB, 0x0002C85D, 0x0001EAAF, 0x0000EB6F,
+ 0x00029E76, 0x00034AC5, 0x000319DF, 0x0003A833, 0x00030738, 0x0002402A, 0x00018CDE, 0x0000C48A,
+ 0x0001F91E, 0x000320B4, 0x0002F23F, 0x0002A6CE, 0x00022469, 0x0001AEE2, 0x000176E7, 0x0000BF20,
+ 0x00015270, 0x0001D56D, 0x00022D8B, 0x0001E479, 0x00019C02, 0x00018EDD, 0x000112BE, 0x0000A87B,
+},
+{
+ 0x00020000, 0x0002C62A, 0x00029CF6, 0x0002CAEF, 0x00020000, 0x0001DDB4, 0x00017D01, 0x0000C23C,
+ 0x0003D07A, 0x00054A69, 0x0005E3CC, 0x0004E499, 0x00048204, 0x0002FF36, 0x00021077, 0x00014AA3,
+ 0x000468DF, 0x00061DCA, 0x00058C50, 0x0004FE3F, 0x00043F0F, 0x0003B8A6, 0x00029032, 0x00014E86,
+ 0x0003F7F5, 0x0005812C, 0x00052F69, 0x00047E65, 0x0004FF5A, 0x0003ED2E, 0x0002B461, 0x00012D11,
+ 0x0003A000, 0x0005072C, 0x000468DF, 0x0003F7F5, 0x0004A000, 0x000356D6, 0x00024CD2, 0x00011A85,
+ 0x0003248D, 0x0003F353, 0x0003B8A6, 0x00046370, 0x0003A243, 0x0002B365, 0x0001DC3E, 0x0000EBD9,
+ 0x00025E24, 0x0003C0D8, 0x00038919, 0x00032E91, 0x00029218, 0x00020510, 0x0001C1E2, 0x0000E559,
+ 0x00019620, 0x0002334F, 0x00029D0D, 0x0002455E, 0x0001EE69, 0x0001DEA2, 0x000149B0, 0x0000CA2D,
+},
+{
+ 0x0002AAAB, 0x0003B2E3, 0x00037BF2, 0x0003B93E, 0x0002AAAB, 0x00027CF0, 0x0001FC01, 0x000102FA,
+ 0x000515F8, 0x00070DE2, 0x0007DA65, 0x00068621, 0x000602B1, 0x0003FEF3, 0x0002C09F, 0x0001B8DA,
+ 0x0005E129, 0x000827B8, 0x000765C0, 0x0006A855, 0x0005A96A, 0x0004F632, 0x00036AED, 0x0001BE09,
+ 0x00054A9C, 0x000756E5, 0x0006E9E2, 0x0005FDDB, 0x0006A9CE, 0x00053C3E, 0x00039B2D, 0x0001916B,
+ 0x0004D555, 0x0006B43B, 0x0005E129, 0x00054A9C, 0x00062AAB, 0x000473C8, 0x00031118, 0x000178B2,
+ 0x000430BC, 0x0005446F, 0x0004F632, 0x0005D9EB, 0x0004D85A, 0x000399DC, 0x00027AFD, 0x00013A77,
+ 0x00032830, 0x00050121, 0x0004B6CC, 0x00043E16, 0x00036D76, 0x0002B16A, 0x000257D8, 0x000131CC,
+ 0x00021D80, 0x0002EF14, 0x00037C11, 0x00030728, 0x00029337, 0x00027E2E, 0x0001B796, 0x00010D91,
+},
+{
+ 0x00038000, 0x0004DACA, 0x000492AE, 0x0004E322, 0x00038000, 0x000343FB, 0x00029AC1, 0x000153E8,
+ 0x0006ACD5, 0x00094238, 0x000A4EA5, 0x0008900C, 0x0007E388, 0x00053E9F, 0x00039CD0, 0x0002429E,
+ 0x0007B786, 0x000AB421, 0x0009B58C, 0x0008BCEF, 0x00076E5B, 0x00068322, 0x00047C57, 0x0002496B,
+ 0x0006F1ED, 0x0009A20D, 0x000912F8, 0x0007DD30, 0x0008BEDE, 0x0006DF11, 0x0004BBAB, 0x00020EDD,
+ 0x00065800, 0x0008CC8E, 0x0007B786, 0x0006F1ED, 0x00081800, 0x0005D7F7, 0x00040670, 0x0001EE69,
+ 0x00057FF7, 0x0006E9D2, 0x00068322, 0x0007AE04, 0x00065BF6, 0x0004B9F1, 0x0003416C, 0x00019CBC,
+ 0x000424BF, 0x0006917B, 0x00062FEB, 0x0005917D, 0x00047FAA, 0x000388DC, 0x0003134C, 0x0001915C,
+ 0x0002C6B8, 0x0003D9CB, 0x000492D7, 0x0003F964, 0x00036138, 0x0003459C, 0x000240F5, 0x000161CF,
+},
+{
+ 0x00040000, 0x00058C54, 0x000539EC, 0x000595DD, 0x00040000, 0x0003BB68, 0x0002FA01, 0x00018477,
+ 0x0007A0F4, 0x000A94D3, 0x000BC798, 0x0009C932, 0x00090409, 0x0005FE6D, 0x000420EE, 0x00029547,
+ 0x0008D1BE, 0x000C3B94, 0x000B18A0, 0x0009FC7F, 0x00087E1F, 0x0007714C, 0x00052064, 0x00029D0D,
+ 0x0007EFEA, 0x000B0258, 0x000A5ED3, 0x0008FCC9, 0x0009FEB5, 0x0007DA5D, 0x000568C3, 0x00025A21,
+ 0x00074000, 0x000A0E59, 0x0008D1BE, 0x0007EFEA, 0x00094000, 0x0006ADAC, 0x000499A5, 0x0002350B,
+ 0x0006491A, 0x0007E6A7, 0x0007714C, 0x0008C6E0, 0x00074487, 0x000566CA, 0x0003B87B, 0x0001D7B3,
+ 0x0004BC48, 0x000781B1, 0x00071232, 0x00065D22, 0x00052430, 0x00040A20, 0x000383C5, 0x0001CAB3,
+ 0x00032C3F, 0x0004669F, 0x00053A1A, 0x00048ABC, 0x0003DCD3, 0x0003BD45, 0x00029361, 0x0001945A,
+},
+{
+ 0x00050000, 0x0006EF69, 0x00068867, 0x0006FB55, 0x00050000, 0x0004AA42, 0x0003B881, 0x0001E595,
+ 0x00098931, 0x000D3A07, 0x000EB97E, 0x000C3B7E, 0x000B450B, 0x00077E08, 0x0005292A, 0x00033A99,
+ 0x000B062D, 0x000F4A78, 0x000DDEC8, 0x000C7B9F, 0x000A9DA7, 0x00094D9F, 0x0006687D, 0x00034450,
+ 0x0009EBE4, 0x000DC2EE, 0x000CF687, 0x000B3BFB, 0x000C7E62, 0x0009D0F4, 0x0006C2F4, 0x0002F0AA,
+ 0x00091000, 0x000C91EF, 0x000B062D, 0x0009EBE4, 0x000B9000, 0x00085917, 0x0005C00E, 0x0002C24D,
+ 0x0007DB61, 0x0009E050, 0x00094D9F, 0x000AF898, 0x000915A8, 0x0006C07D, 0x0004A69A, 0x00024D9F,
+ 0x0005EB59, 0x0009621D, 0x0008D6BE, 0x0007F46A, 0x00066D3C, 0x00050CA7, 0x000464B6, 0x00023D5F,
+ 0x0003F74F, 0x00058046, 0x000688A0, 0x0005AD6B, 0x0004D407, 0x0004AC96, 0x00033839, 0x0001F971,
+},
+{
+ 0x00060000, 0x0008527E, 0x0007D6E1, 0x000860CC, 0x00060000, 0x0005991C, 0x00047702, 0x000246B3,
+ 0x000B716E, 0x000FDF3C, 0x0011AB63, 0x000EADCB, 0x000D860D, 0x0008FDA3, 0x00063165, 0x0003DFEA,
+ 0x000D3A9C, 0x0012595D, 0x0010A4F0, 0x000EFABE, 0x000CBD2E, 0x000B29F1, 0x0007B096, 0x0003EB93,
+ 0x000BE7DF, 0x00108384, 0x000F8E3C, 0x000D7B2E, 0x000EFE0F, 0x000BC78B, 0x00081D24, 0x00038732,
+ 0x000AE000, 0x000F1585, 0x000D3A9C, 0x000BE7DF, 0x000DE000, 0x000A0482, 0x0006E677, 0x00034F90,
+ 0x00096DA8, 0x000BD9FA, 0x000B29F1, 0x000D2A50, 0x000AE6CA, 0x00081A2F, 0x000594B9, 0x0002C38C,
+ 0x00071A6B, 0x000B4289, 0x000A9B4A, 0x00098BB2, 0x0007B649, 0x00060F2F, 0x000545A7, 0x0002B00C,
+ 0x0004C25F, 0x000699EE, 0x0007D727, 0x0006D01A, 0x0005CB3C, 0x00059BE7, 0x0003DD11, 0x00025E87,
+},
+{
+ 0x00080000, 0x000B18A8, 0x000A73D7, 0x000B2BBB, 0x00080000, 0x000776CF, 0x0005F402, 0x000308EF,
+ 0x000F41E8, 0x001529A5, 0x00178F2F, 0x00139264, 0x00120812, 0x000BFCD9, 0x000841DC, 0x00052A8E,
+ 0x0011A37B, 0x00187727, 0x00163140, 0x0013F8FE, 0x0010FC3E, 0x000EE297, 0x000A40C8, 0x00053A1A,
+ 0x000FDFD4, 0x001604B0, 0x0014BDA5, 0x0011F992, 0x0013FD69, 0x000FB4B9, 0x000AD186, 0x0004B442,
+ 0x000E8000, 0x00141CB1, 0x0011A37B, 0x000FDFD4, 0x00128000, 0x000D5B58, 0x00093349, 0x00046A15,
+ 0x000C9235, 0x000FCD4D, 0x000EE297, 0x00118DC0, 0x000E890D, 0x000ACD94, 0x000770F7, 0x0003AF65,
+ 0x0009788F, 0x000F0362, 0x000E2463, 0x000CBA43, 0x000A4861, 0x0008143F, 0x00070789, 0x00039565,
+ 0x0006587F, 0x0008CD3D, 0x000A7434, 0x00091577, 0x0007B9A6, 0x00077A89, 0x000526C2, 0x000328B4,
+},
+{
+ 0x000C0000, 0x0010A4FD, 0x000FADC3, 0x0010C198, 0x000C0000, 0x000B3237, 0x0008EE03, 0x00048D66,
+ 0x0016E2DB, 0x001FBE78, 0x002356C7, 0x001D5B96, 0x001B0C1A, 0x0011FB46, 0x000C62CA, 0x0007BFD5,
+ 0x001A7539, 0x0024B2BB, 0x002149E1, 0x001DF57D, 0x00197A5D, 0x001653E3, 0x000F612C, 0x0007D727,
+ 0x0017CFBD, 0x00210709, 0x001F1C78, 0x001AF65B, 0x001DFC1E, 0x00178F16, 0x00103A49, 0x00070E64,
+ 0x0015C000, 0x001E2B0A, 0x001A7539, 0x0017CFBD, 0x001BC000, 0x00140904, 0x000DCCEE, 0x00069F20,
+ 0x0012DB4F, 0x0017B3F4, 0x001653E3, 0x001A54A0, 0x0015CD94, 0x0010345E, 0x000B2972, 0x00058718,
+ 0x000E34D7, 0x00168513, 0x00153695, 0x00131765, 0x000F6C91, 0x000C1E5E, 0x000A8B4E, 0x00056018,
+ 0x000984BE, 0x000D33DC, 0x000FAE4E, 0x000DA033, 0x000B9678, 0x000B37CE, 0x0007BA22, 0x0004BD0E,
+},
+{
+ 0x00110000, 0x00179466, 0x0016362A, 0x0017BCED, 0x00110000, 0x000FDC79, 0x000CA685, 0x000672FB,
+ 0x00206C0C, 0x002CF87F, 0x00321044, 0x00299714, 0x00265125, 0x0019794E, 0x00118BF4, 0x000AFA6D,
+ 0x00257B66, 0x0033FD33, 0x002F28A9, 0x002A711B, 0x00241804, 0x001FA181, 0x0015C9A9, 0x000B1B77,
+ 0x0021BBA2, 0x002EC9F7, 0x002C12FF, 0x00263256, 0x002A7A80, 0x0021600A, 0x0016FD3C, 0x0009FF0D,
+ 0x001ED000, 0x002ABCF9, 0x00257B66, 0x0021BBA2, 0x00275000, 0x001C621B, 0x00138CFB, 0x0009616E,
+ 0x001AB6B0, 0x00219444, 0x001FA181, 0x00254D38, 0x001EE33C, 0x0016F4DB, 0x000FD00C, 0x0007D4B7,
+ 0x00142030, 0x001FE730, 0x001E0D52, 0x001B0BCF, 0x0015D9CE, 0x00112B06, 0x000EF004, 0x00079D77,
+ 0x000D7C0E, 0x0012B423, 0x001636EE, 0x00134D9E, 0x00106A80, 0x000FE464, 0x000AF25B, 0x0006B67F,
+},
+{
+ 0x00160000, 0x001E83CF, 0x001CBE90, 0x001EB842, 0x00160000, 0x001486BA, 0x00105F06, 0x00085891,
+ 0x0029F53D, 0x003A3286, 0x0040C9C2, 0x0035D293, 0x00319630, 0x0020F756, 0x0016B51E, 0x000E3506,
+ 0x00308193, 0x004347AC, 0x003D0771, 0x0036ECBA, 0x002EB5AA, 0x0028EF20, 0x001C3225, 0x000E5FC7,
+ 0x002BA786, 0x003C8CE5, 0x00390986, 0x00316E52, 0x0036F8E1, 0x002B30FE, 0x001DC030, 0x000CEFB7,
+ 0x0027E000, 0x00374EE7, 0x00308193, 0x002BA786, 0x0032E000, 0x0024BB33, 0x00194D09, 0x000C23BB,
+ 0x00229212, 0x002B7494, 0x0028EF20, 0x003045D0, 0x0027F8E4, 0x001DB557, 0x001476A6, 0x000A2256,
+ 0x001A0B89, 0x0029494D, 0x0026E410, 0x00230039, 0x001C470A, 0x001637AD, 0x001354B9, 0x0009DAD6,
+ 0x0011735D, 0x00183469, 0x001CBF8F, 0x0018FB09, 0x00153E87, 0x001490FA, 0x000E2A94, 0x0008AFF0,
+},
+{
+ 0x001C0000, 0x0026D64D, 0x00249572, 0x0027190E, 0x001C0000, 0x001A1FD6, 0x0014D607, 0x000A9F44,
+ 0x003566AA, 0x004A11C2, 0x00527525, 0x0044805E, 0x003F1C3E, 0x0029F4F9, 0x001CE683, 0x001214F0,
+ 0x003DBC30, 0x0055A109, 0x004DAC61, 0x0045E778, 0x003B72D9, 0x00341911, 0x0023E2BB, 0x00124B5B,
+ 0x00378F64, 0x004D1069, 0x004897C2, 0x003EE97F, 0x0045F6F0, 0x0036F889, 0x0025DD54, 0x001076E9,
+ 0x0032C000, 0x0046646C, 0x003DBC30, 0x00378F64, 0x0040C000, 0x002EBFB5, 0x00203380, 0x000F734B,
+ 0x002BFFB9, 0x00374E8E, 0x00341911, 0x003D7020, 0x0032DFAE, 0x0025CF86, 0x001A0B5F, 0x000CE5E2,
+ 0x002125F5, 0x00348BD6, 0x00317F5B, 0x002C8BEB, 0x0023FD53, 0x001C46DC, 0x00189A60, 0x000C8AE2,
+ 0x001635BC, 0x001ECE57, 0x002496B6, 0x001FCB22, 0x001B09C4, 0x001A2CE1, 0x001207A5, 0x000B0E77,
+},
+{
+ 0x00220000, 0x002F28CC, 0x002C6C53, 0x002F79DA, 0x00220000, 0x001FB8F1, 0x00194D09, 0x000CE5F7,
+ 0x0040D818, 0x0059F0FE, 0x00642089, 0x00532E29, 0x004CA24B, 0x0032F29C, 0x002317E8, 0x0015F4DB,
+ 0x004AF6CC, 0x0067FA67, 0x005E5152, 0x0054E237, 0x00483007, 0x003F4303, 0x002B9351, 0x001636EE,
+ 0x00437743, 0x005D93EE, 0x005825FE, 0x004C64AD, 0x0054F4FF, 0x0042C014, 0x002DFA79, 0x0013FE1A,
+ 0x003DA000, 0x005579F1, 0x004AF6CC, 0x00437743, 0x004EA000, 0x0038C437, 0x002719F7, 0x0012C2DB,
+ 0x00356D61, 0x00432888, 0x003F4303, 0x004A9A70, 0x003DC678, 0x002DE9B5, 0x001FA018, 0x000FA96E,
+ 0x00284060, 0x003FCE60, 0x003C1AA5, 0x0036179D, 0x002BB39B, 0x0022560C, 0x001DE007, 0x000F3AEE,
+ 0x001AF81B, 0x00256845, 0x002C6DDD, 0x00269B3C, 0x0020D500, 0x001FC8C8, 0x0015E4B7, 0x000D6CFE,
+},
+{
+ 0x002C0000, 0x003D079E, 0x00397D20, 0x003D7083, 0x002C0000, 0x00290D75, 0x0020BE0C, 0x0010B121,
+ 0x0053EA79, 0x0074650C, 0x00819383, 0x006BA525, 0x00632C61, 0x0041EEAC, 0x002D6A3B, 0x001C6A0C,
+ 0x00610326, 0x00868F57, 0x007A0EE2, 0x006DD974, 0x005D6B54, 0x0051DE40, 0x0038644B, 0x001CBF8F,
+ 0x00574F0B, 0x007919CA, 0x0072130C, 0x0062DCA3, 0x006DF1C2, 0x005661FB, 0x003B8060, 0x0019DF6D,
+ 0x004FC000, 0x006E9DCE, 0x00610326, 0x00574F0B, 0x0065C000, 0x00497665, 0x00329A12, 0x00184776,
+ 0x00452423, 0x0056E928, 0x0051DE40, 0x00608BA0, 0x004FF1C9, 0x003B6AAE, 0x0028ED4D, 0x001444AC,
+ 0x00341713, 0x0052929A, 0x004DC821, 0x00460071, 0x00388E14, 0x002C6F5A, 0x0026A973, 0x0013B5AD,
+ 0x0022E6BA, 0x003068D2, 0x00397F1E, 0x0031F611, 0x002A7D0F, 0x002921F4, 0x001C5528, 0x00115FDF,
+}
+};
+
+static const uint32_t bink_inter_quant[16][64] = {
+{
+ 0x00010000, 0x00017946, 0x00016363, 0x000152A7, 0x00012000, 0x0000E248, 0x0000A486, 0x000053E0,
+ 0x0001A5A9, 0x000248DC, 0x000243EC, 0x000209EA, 0x0001BBDA, 0x00015CBC, 0x0000F036, 0x00008095,
+ 0x0001B701, 0x000260EB, 0x00023D97, 0x00020437, 0x0001B701, 0x00016959, 0x0000F8E7, 0x00007EE4,
+ 0x00019DE9, 0x00023E1B, 0x00021CCC, 0x0001E6B4, 0x0001B0B9, 0x000153FD, 0x0000EA30, 0x00007763,
+ 0x00017000, 0x0001FE6E, 0x0001E0D1, 0x0001B0B9, 0x00018000, 0x00012DB5, 0x0000CFD2, 0x00006E5C,
+ 0x00012DB5, 0x0001A27B, 0x00018A33, 0x0001718D, 0x000146D9, 0x000100CE, 0x0000B0E4, 0x00005A2D,
+ 0x0000D87A, 0x00014449, 0x00013178, 0x000112EA, 0x0000E9CC, 0x0000B7B1, 0x00008337, 0x000042E5,
+ 0x00007B9A, 0x0000AB71, 0x0000AD08, 0x00009BB9, 0x0000846F, 0x00006B85, 0x00004A10, 0x00002831,
+},
+{
+ 0x00015555, 0x0001F708, 0x0001D9D9, 0x0001C389, 0x00018000, 0x00012DB5, 0x0000DB5D, 0x00006FD5,
+ 0x00023237, 0x00030BD0, 0x0003053B, 0x0002B7E3, 0x00024FCE, 0x0001D0FA, 0x00014048, 0x0000AB71,
+ 0x00024957, 0x00032BE4, 0x0002FCC9, 0x0002B04A, 0x00024957, 0x0001E1CC, 0x00014BDE, 0x0000A92F,
+ 0x000227E1, 0x0002FD7A, 0x0002D110, 0x000288F1, 0x000240F7, 0x0001C551, 0x00013840, 0x00009F2F,
+ 0x0001EAAB, 0x0002A893, 0x00028116, 0x000240F7, 0x00020000, 0x00019247, 0x00011518, 0x00009325,
+ 0x00019247, 0x00022DF9, 0x00020D99, 0x0001ECBC, 0x0001B3CC, 0x00015668, 0x0000EBDA, 0x0000783D,
+ 0x000120A3, 0x0001B061, 0x0001974B, 0x00016E8E, 0x000137BB, 0x0000F4ED, 0x0000AEF4, 0x00005931,
+ 0x0000A4CE, 0x0000E497, 0x0000E6B5, 0x0000CFA2, 0x0000B093, 0x00008F5C, 0x000062BF, 0x00003597,
+},
+{
+ 0x0001AAAB, 0x000274CB, 0x0002504F, 0x0002346C, 0x0001E000, 0x00017922, 0x00011235, 0x00008BCA,
+ 0x0002BEC4, 0x0003CEC4, 0x0003C689, 0x000365DC, 0x0002E3C1, 0x00024539, 0x0001905A, 0x0000D64D,
+ 0x0002DBAD, 0x0003F6DD, 0x0003BBFB, 0x00035C5C, 0x0002DBAD, 0x00025A40, 0x00019ED6, 0x0000D37B,
+ 0x0002B1D9, 0x0003BCD8, 0x00038554, 0x00032B2D, 0x0002D134, 0x000236A5, 0x00018650, 0x0000C6FB,
+ 0x00026555, 0x000352B8, 0x0003215C, 0x0002D134, 0x00028000, 0x0001F6D8, 0x00015A5E, 0x0000B7EF,
+ 0x0001F6D8, 0x0002B977, 0x00029100, 0x000267EB, 0x000220C0, 0x0001AC02, 0x000126D1, 0x0000964C,
+ 0x000168CC, 0x00021C7A, 0x0001FD1E, 0x0001CA31, 0x000185A9, 0x00013228, 0x0000DAB2, 0x00006F7D,
+ 0x0000CE01, 0x00011DBD, 0x00012062, 0x0001038A, 0x0000DCB8, 0x0000B333, 0x00007B6F, 0x000042FC,
+},
+{
+ 0x00020000, 0x0002F28D, 0x0002C6C5, 0x0002A54E, 0x00024000, 0x0001C48F, 0x0001490C, 0x0000A7BF,
+ 0x00034B52, 0x000491B8, 0x000487D8, 0x000413D5, 0x000377B5, 0x0002B977, 0x0001E06C, 0x0001012A,
+ 0x00036E03, 0x0004C1D6, 0x00047B2D, 0x0004086E, 0x00036E03, 0x0002D2B3, 0x0001F1CE, 0x0000FDC7,
+ 0x00033BD1, 0x00047C37, 0x00043998, 0x0003CD69, 0x00036172, 0x0002A7FA, 0x0001D460, 0x0000EEC7,
+ 0x0002E000, 0x0003FCDD, 0x0003C1A1, 0x00036172, 0x00030000, 0x00025B6A, 0x00019FA3, 0x0000DCB8,
+ 0x00025B6A, 0x000344F5, 0x00031466, 0x0002E31B, 0x00028DB3, 0x0002019B, 0x000161C7, 0x0000B45B,
+ 0x0001B0F5, 0x00028892, 0x000262F1, 0x000225D5, 0x0001D398, 0x00016F63, 0x0001066F, 0x000085C9,
+ 0x0000F735, 0x000156E2, 0x00015A10, 0x00013772, 0x000108DD, 0x0000D70A, 0x0000941F, 0x00005062,
+},
+{
+ 0x0002AAAB, 0x0003EE11, 0x0003B3B2, 0x00038713, 0x00030000, 0x00025B6A, 0x0001B6BB, 0x0000DFAA,
+ 0x0004646D, 0x000617A0, 0x00060A75, 0x00056FC6, 0x00049F9B, 0x0003A1F4, 0x00028090, 0x000156E2,
+ 0x000492AE, 0x000657C8, 0x0005F991, 0x00056093, 0x000492AE, 0x0003C399, 0x000297BD, 0x0001525F,
+ 0x00044FC1, 0x0005FAF4, 0x0005A220, 0x000511E1, 0x000481ED, 0x00038AA2, 0x00027080, 0x00013E5E,
+ 0x0003D555, 0x00055126, 0x0005022D, 0x000481ED, 0x00040000, 0x0003248D, 0x00022A2F, 0x0001264B,
+ 0x0003248D, 0x00045BF2, 0x00041B33, 0x0003D979, 0x00036799, 0x0002ACCF, 0x0001D7B5, 0x0000F079,
+ 0x00024147, 0x000360C3, 0x00032E96, 0x0002DD1C, 0x00026F75, 0x0001E9D9, 0x00015DE9, 0x0000B262,
+ 0x0001499C, 0x0001C92E, 0x0001CD6A, 0x00019F43, 0x00016127, 0x00011EB8, 0x0000C57F, 0x00006B2D,
+},
+{
+ 0x00038000, 0x00052876, 0x0004DBD9, 0x0004A148, 0x0003F000, 0x000317FB, 0x00023FD5, 0x0001258F,
+ 0x0005C3CF, 0x0007FF02, 0x0007EDBA, 0x000722B4, 0x0006117C, 0x0004C491, 0x000348BD, 0x0001C209,
+ 0x00060085, 0x00085336, 0x0007D78F, 0x00070EC1, 0x00060085, 0x0004F0B9, 0x00036728, 0x0001BC1C,
+ 0x0005A8AE, 0x0007D960, 0x000764CA, 0x0006A777, 0x0005EA87, 0x0004A5F5, 0x000333A8, 0x0001A1DB,
+ 0x00050800, 0x0006FA82, 0x000692DA, 0x0005EA87, 0x00054000, 0x00041FF9, 0x0002D75E, 0x00018242,
+ 0x00041FF9, 0x0005B8AE, 0x000563B2, 0x00050D6E, 0x000477F9, 0x000382D0, 0x00026B1D, 0x00013B9F,
+ 0x0002F5AD, 0x00046F00, 0x00042D25, 0x0003C235, 0x0003324A, 0x000282ED, 0x0001CB42, 0x0000EA21,
+ 0x0001B09C, 0x0002580C, 0x00025D9B, 0x00022108, 0x0001CF83, 0x00017851, 0x00010336, 0x00008CAC,
+},
+{
+ 0x00040000, 0x0005E519, 0x00058D8A, 0x00054A9C, 0x00048000, 0x0003891F, 0x00029218, 0x00014F7E,
+ 0x000696A4, 0x00092370, 0x00090FB0, 0x000827AA, 0x0006EF69, 0x000572EE, 0x0003C0D8, 0x00020254,
+ 0x0006DC05, 0x000983AC, 0x0008F65A, 0x000810DD, 0x0006DC05, 0x0005A565, 0x0003E39B, 0x0001FB8E,
+ 0x000677A2, 0x0008F86E, 0x00087330, 0x00079AD1, 0x0006C2E4, 0x00054FF3, 0x0003A8C0, 0x0001DD8D,
+ 0x0005C000, 0x0007F9B9, 0x00078343, 0x0006C2E4, 0x00060000, 0x0004B6D4, 0x00033F47, 0x0001B970,
+ 0x0004B6D4, 0x000689EB, 0x000628CC, 0x0005C635, 0x00051B65, 0x00040337, 0x0002C38F, 0x000168B6,
+ 0x000361EA, 0x00051124, 0x0004C5E1, 0x00044BAA, 0x0003A730, 0x0002DEC6, 0x00020CDD, 0x00010B93,
+ 0x0001EE69, 0x0002ADC5, 0x0002B41F, 0x00026EE5, 0x000211BA, 0x0001AE14, 0x0001283E, 0x0000A0C4,
+},
+{
+ 0x00050000, 0x00075E60, 0x0006F0ED, 0x00069D43, 0x0005A000, 0x00046B67, 0x0003369E, 0x0001A35E,
+ 0x00083C4D, 0x000B6C4C, 0x000B539C, 0x000A3194, 0x0008AB44, 0x0006CFAA, 0x0004B10F, 0x000282E8,
+ 0x00089307, 0x000BE497, 0x000B33F1, 0x000A1514, 0x00089307, 0x00070EBF, 0x0004DC82, 0x00027A72,
+ 0x0008158B, 0x000B3689, 0x000A8FFC, 0x00098186, 0x0008739C, 0x0006A3F0, 0x000492F0, 0x000254F0,
+ 0x00073000, 0x0009F827, 0x00096413, 0x0008739C, 0x00078000, 0x0005E489, 0x00040F19, 0x000227CC,
+ 0x0005E489, 0x00082C66, 0x0007B2FF, 0x000737C2, 0x0006623F, 0x00050405, 0x00037473, 0x0001C2E3,
+ 0x00043A64, 0x0006556D, 0x0005F75A, 0x00055E94, 0x000490FC, 0x00039677, 0x00029015, 0x00014E78,
+ 0x00026A04, 0x00035936, 0x00036127, 0x00030A9E, 0x00029629, 0x00021999, 0x0001724E, 0x0000C8F5,
+},
+{
+ 0x00060000, 0x0008D7A6, 0x00085450, 0x0007EFEA, 0x0006C000, 0x00054DAE, 0x0003DB24, 0x0001F73E,
+ 0x0009E1F6, 0x000DB528, 0x000D9788, 0x000C3B7E, 0x000A671E, 0x00082C66, 0x0005A145, 0x0003037D,
+ 0x000A4A08, 0x000E4582, 0x000D7187, 0x000C194B, 0x000A4A08, 0x00087818, 0x0005D569, 0x0002F955,
+ 0x0009B373, 0x000D74A5, 0x000CACC8, 0x000B683A, 0x000A2455, 0x0007F7ED, 0x00057D20, 0x0002CC54,
+ 0x0008A000, 0x000BF696, 0x000B44E4, 0x000A2455, 0x00090000, 0x0007123E, 0x0004DEEA, 0x00029629,
+ 0x0007123E, 0x0009CEE0, 0x00093D32, 0x0008A950, 0x0007A918, 0x000604D2, 0x00042556, 0x00021D11,
+ 0x000512DF, 0x000799B6, 0x000728D2, 0x0006717F, 0x00057AC8, 0x00044E28, 0x0003134C, 0x0001915C,
+ 0x0002E59E, 0x000404A7, 0x00040E2F, 0x0003A657, 0x00031A97, 0x0002851E, 0x0001BC5D, 0x0000F126,
+},
+{
+ 0x00080000, 0x000BCA33, 0x000B1B15, 0x000A9538, 0x00090000, 0x0007123E, 0x00052430, 0x00029EFD,
+ 0x000D2D48, 0x001246E0, 0x00121F5F, 0x00104F53, 0x000DDED2, 0x000AE5DD, 0x000781B1, 0x000404A7,
+ 0x000DB80B, 0x00130757, 0x0011ECB4, 0x001021B9, 0x000DB80B, 0x000B4ACB, 0x0007C736, 0x0003F71D,
+ 0x000CEF44, 0x0011F0DC, 0x0010E661, 0x000F35A3, 0x000D85C7, 0x000A9FE7, 0x00075180, 0x0003BB1A,
+ 0x000B8000, 0x000FF372, 0x000F0686, 0x000D85C7, 0x000C0000, 0x00096DA8, 0x00067E8E, 0x000372E1,
+ 0x00096DA8, 0x000D13D6, 0x000C5198, 0x000B8C6A, 0x000A36CB, 0x0008066E, 0x0005871E, 0x0002D16B,
+ 0x0006C3D4, 0x000A2248, 0x00098BC3, 0x00089754, 0x00074E60, 0x0005BD8B, 0x000419BB, 0x00021726,
+ 0x0003DCD3, 0x00055B8A, 0x0005683E, 0x0004DDC9, 0x00042374, 0x00035C28, 0x0002507C, 0x00014188,
+},
+{
+ 0x000C0000, 0x0011AF4C, 0x0010A89F, 0x000FDFD4, 0x000D8000, 0x000A9B5D, 0x0007B649, 0x0003EE7B,
+ 0x0013C3EC, 0x001B6A50, 0x001B2F0F, 0x001876FD, 0x0014CE3C, 0x001058CB, 0x000B4289, 0x000606FB,
+ 0x00149410, 0x001C8B03, 0x001AE30E, 0x00183296, 0x00149410, 0x0010F030, 0x000BAAD2, 0x0005F2AB,
+ 0x001366E6, 0x001AE949, 0x00195991, 0x0016D074, 0x001448AB, 0x000FEFDA, 0x000AFA40, 0x000598A7,
+ 0x00114000, 0x0017ED2B, 0x001689C8, 0x001448AB, 0x00120000, 0x000E247C, 0x0009BDD5, 0x00052C51,
+ 0x000E247C, 0x00139DC1, 0x00127A63, 0x0011529F, 0x000F5230, 0x000C09A5, 0x00084AAC, 0x00043A21,
+ 0x000A25BE, 0x000F336D, 0x000E51A4, 0x000CE2FE, 0x000AF590, 0x00089C51, 0x00062698, 0x000322B9,
+ 0x0005CB3C, 0x0008094E, 0x00081C5D, 0x00074CAE, 0x0006352E, 0x00050A3B, 0x000378BA, 0x0001E24D,
+},
+{
+ 0x00110000, 0x00190DAC, 0x0017998C, 0x00167D16, 0x00132000, 0x000F06C3, 0x000AECE7, 0x000591D9,
+ 0x001C0039, 0x0026D69C, 0x002682AB, 0x0022A891, 0x001D797F, 0x00172876, 0x000FF398, 0x000889E3,
+ 0x001D2717, 0x00286F9A, 0x002616FF, 0x002247AA, 0x001D2717, 0x0017FEEF, 0x00108754, 0x00086D1D,
+ 0x001B7C71, 0x00261FD3, 0x0023E98D, 0x002051FA, 0x001CBC47, 0x001693CA, 0x000F8D30, 0x0007ED98,
+ 0x00187000, 0x0021E552, 0x001FEDDC, 0x001CBC47, 0x00198000, 0x00140904, 0x000DCCEE, 0x0007541E,
+ 0x00140904, 0x001BCA27, 0x001A2D62, 0x00188A62, 0x0015B46F, 0x00110DAA, 0x000BBF1F, 0x0005FD04,
+ 0x000E6022, 0x001588DA, 0x001448FE, 0x00124192, 0x000F868B, 0x000C32C8, 0x0008B6AD, 0x00047130,
+ 0x00083540, 0x000B6284, 0x000B7D84, 0x000A574B, 0x0008CB57, 0x000723D4, 0x0004EB08, 0x0002AB42,
+},
+{
+ 0x00160000, 0x00206C0C, 0x001E8A79, 0x001D1A59, 0x0018C000, 0x0013722A, 0x000E2385, 0x00073537,
+ 0x00243C86, 0x003242E8, 0x0031D646, 0x002CDA25, 0x002624C3, 0x001DF820, 0x0014A4A7, 0x000B0CCC,
+ 0x0025BA1D, 0x00345430, 0x00314AEF, 0x002C5CBE, 0x0025BA1D, 0x001F0DAE, 0x001563D6, 0x000AE78E,
+ 0x002391FB, 0x0031565C, 0x002E798A, 0x0029D380, 0x00252FE4, 0x001D37BB, 0x00142021, 0x000A4288,
+ 0x001FA000, 0x002BDD7A, 0x002951EF, 0x00252FE4, 0x00210000, 0x0019ED8D, 0x0011DC06, 0x00097BEA,
+ 0x0019ED8D, 0x0023F68C, 0x0021E061, 0x001FC224, 0x001C16AE, 0x001611AE, 0x000F3391, 0x0007BFE7,
+ 0x00129A87, 0x001BDE47, 0x001A4058, 0x0017A026, 0x00141787, 0x000FC93E, 0x000B46C1, 0x0005BFA8,
+ 0x000A9F44, 0x000EBBBA, 0x000EDEAB, 0x000D61E9, 0x000B617F, 0x00093D6D, 0x00065D55, 0x00037437,
+},
+{
+ 0x001C0000, 0x002943B2, 0x0026DEC9, 0x00250A43, 0x001F8000, 0x0018BFD8, 0x0011FEA9, 0x00092C75,
+ 0x002E1E7C, 0x003FF810, 0x003F6DCE, 0x003915A3, 0x00308BE1, 0x00262485, 0x001A45EB, 0x000E1049,
+ 0x00300425, 0x004299B2, 0x003EBC76, 0x00387608, 0x00300425, 0x002785C6, 0x001B393F, 0x000DE0E4,
+ 0x002D456E, 0x003ECB00, 0x003B2652, 0x00353BBA, 0x002F5439, 0x00252FA8, 0x00199D41, 0x000D0EDC,
+ 0x00284000, 0x0037D40F, 0x003496D3, 0x002F5439, 0x002A0000, 0x0020FFCB, 0x0016BAF1, 0x000C1213,
+ 0x0020FFCB, 0x002DC56D, 0x002B1D93, 0x00286B74, 0x0023BFC6, 0x001C1681, 0x001358E8, 0x0009DCF8,
+ 0x0017AD66, 0x002377FE, 0x0021692A, 0x001E11A5, 0x0019924F, 0x00141767, 0x000E5A0D, 0x00075104,
+ 0x000D84E2, 0x0012C062, 0x0012ECDA, 0x00110840, 0x000E7C16, 0x000BC28A, 0x000819B2, 0x0004655D,
+},
+{
+ 0x00220000, 0x00321B58, 0x002F3318, 0x002CFA2D, 0x00264000, 0x001E0D86, 0x0015D9CE, 0x000B23B2,
+ 0x00380072, 0x004DAD38, 0x004D0556, 0x00455122, 0x003AF2FE, 0x002E50EB, 0x001FE730, 0x001113C7,
+ 0x003A4E2D, 0x0050DF33, 0x004C2DFD, 0x00448F54, 0x003A4E2D, 0x002FFDDF, 0x00210EA8, 0x0010DA39,
+ 0x0036F8E1, 0x004C3FA5, 0x0047D31B, 0x0040A3F5, 0x0039788E, 0x002D2795, 0x001F1A61, 0x000FDB2F,
+ 0x0030E000, 0x0043CAA5, 0x003FDBB7, 0x0039788E, 0x00330000, 0x00281209, 0x001B99DB, 0x000EA83B,
+ 0x00281209, 0x0037944D, 0x00345AC4, 0x003114C3, 0x002B68DF, 0x00221B53, 0x00177E3E, 0x000BFA09,
+ 0x001CC044, 0x002B11B4, 0x002891FC, 0x00248324, 0x001F0D17, 0x0018658F, 0x00116D5A, 0x0008E260,
+ 0x00106A80, 0x0016C509, 0x0016FB08, 0x0014AE97, 0x001196AE, 0x000E47A8, 0x0009D60F, 0x00055684,
+},
+{
+ 0x002C0000, 0x0040D818, 0x003D14F2, 0x003A34B2, 0x00318000, 0x0026E454, 0x001C470A, 0x000E6A6E,
+ 0x0048790C, 0x006485D0, 0x0063AC8D, 0x0059B44A, 0x004C4986, 0x003BF03F, 0x0029494D, 0x00161998,
+ 0x004B743A, 0x0068A861, 0x006295DE, 0x0058B97B, 0x004B743A, 0x003E1B5C, 0x002AC7AC, 0x0015CF1D,
+ 0x004723F6, 0x0062ACB8, 0x005CF313, 0x0053A701, 0x004A5FC7, 0x003A6F75, 0x00284041, 0x00148510,
+ 0x003F4000, 0x0057BAF3, 0x0052A3DE, 0x004A5FC7, 0x00420000, 0x0033DB1A, 0x0023B80D, 0x0012F7D4,
+ 0x0033DB1A, 0x0047ED19, 0x0043C0C2, 0x003F8448, 0x00382D5C, 0x002C235D, 0x001E6723, 0x000F7FCF,
+ 0x0025350D, 0x0037BC8E, 0x003480B0, 0x002F404C, 0x00282F0E, 0x001F927D, 0x00168D83, 0x000B7F50,
+ 0x00153E87, 0x001D7775, 0x001DBD56, 0x001AC3D2, 0x0016C2FF, 0x00127AD9, 0x000CBAAA, 0x0006E86E,
+}
+};
+
+#endif /* AVCODEC_BINKDATA_H */
diff --git a/libavcodec/dct.c b/libavcodec/dct.c
new file mode 100644
index 0000000..806b4ea
--- /dev/null
+++ b/libavcodec/dct.c
@@ -0,0 +1,95 @@
+/*
+ * (I)DCT Transforms
+ * Copyright (c) 2009 Peter Ross (pross at xvid.org)
+ *
+ * This file is part of FFmpeg.
+ *
+ * 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.
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/**
+ * @file libavcodec/dct.c
+ * (Inverse) Discrete Cosine Transforms
+ */
+
+#include <math.h>
+#include "dsputil.h"
+
+av_cold int ff_dct_init(DCTContext *s, int nbits, int inverse)
+{
+    int n = 1 << nbits;
+
+    s->nbits    = nbits;
+    s->inverse  = inverse;
+
+    s->data = av_malloc(sizeof(FFTComplex) * 2 * n);
+    if (!s->data)
+        return -1;
+
+    if (ff_fft_init(&s->fft, nbits+1, inverse) < 0)
+        return -1;
+
+    return 0;
+}
+
+static void ff_dct_calc_c(DCTContext *s, FFTSample *data)
+{
+    int n = 1<<s->nbits;
+    int i;
+
+#define ROTATE(i,n) (-M_PI*((n)-0.5f)*(i)/(n))
+    if (s->inverse) {
+        for(i=0; i < n; i++) {
+            s->data[i].re = 2 * data[i] * cos(ROTATE(i,n));
+            s->data[i].im = 2 * data[i] * sin(ROTATE(i,n));
+        }
+        s->data[n].re = 0;
+        s->data[n].im = 0;
+        for(i=0; i<n-1; i++) {
+            s->data[n+i+1].re = -2 * data[n - (i+1)] * cos(ROTATE(n+i+1,n));
+            s->data[n+i+1].im = -2 * data[n - (i+1)] * sin(ROTATE(n+i+1,n));
+        }
+    }else{
+        for(i=0; i < n; i++) {
+            s->data[i].re = data[n - (i+1)];
+            s->data[i].im = 0;
+            s->data[n+i].re = data[i];
+            s->data[n+i].im = 0;
+        }
+    }
+
+    ff_fft_permute(&s->fft, s->data);
+    ff_fft_calc(&s->fft, s->data);
+
+    if (s->inverse) {
+        for(i=0; i < n; i++)
+            data[i] = s->data[n-(i+1)].re / (2 * n);
+    }else {
+        for(i=0; i < n; i++)
+            data[i] = s->data[i].re / (2 * cos(ROTATE(i,n)));
+    }
+#undef ROTATE
+}
+
+void ff_dct_calc(DCTContext *s, FFTSample *data)
+{
+    ff_dct_calc_c(s, data);
+}
+
+av_cold void ff_dct_end(DCTContext *s)
+{
+    ff_fft_end(&s->fft);
+    av_free(s->data);
+}
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index 104953f..9776a74 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -800,6 +800,24 @@ int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans);
 void ff_rdft_calc(RDFTContext *s, FFTSample *data);
 void ff_rdft_end(RDFTContext *s);
 
+/* Discrete Cosine Transform */
+
+typedef struct {
+    int nbits;
+    int inverse;
+    FFTComplex *data;
+    FFTContext fft;
+} DCTContext;
+
+/**
+ * Sets up (Inverse)DCT.
+ * @param nbits           log2 of the length of the input array
+ * @param inverse         >0 forward transform, <0 inverse transform
+ */
+int ff_dct_init(DCTContext *s, int nbits, int inverse);
+void ff_dct_calc(DCTContext *s, FFTSample *data);
+void ff_dct_end(DCTContext *s);
+
 #define WRAPPER8_16(name8, name16)\
 static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
     return name8(s, dst           , src           , stride, h)\
diff --git a/libavcodec/wma.c b/libavcodec/wma.c
index 4fc4922..bcded48 100644
--- a/libavcodec/wma.c
+++ b/libavcodec/wma.c
@@ -238,7 +238,7 @@ int ff_wma_init(AVCodecContext *avctx, int flags2)
             if (s->version == 1) {
                 lpos = 0;
                 for (i = 0; i < 25; i++) {
-                    a = wma_critical_freqs[i];
+                    a = ff_wma_critical_freqs[i];
                     b = s->sample_rate;
                     pos = ((block_len * 2 * a) + (b >> 1)) / b;
                     if (pos > block_len)
@@ -273,7 +273,7 @@ int ff_wma_init(AVCodecContext *avctx, int flags2)
                     j = 0;
                     lpos = 0;
                     for (i = 0; i < 25; i++) {
-                        a = wma_critical_freqs[i];
+                        a = ff_wma_critical_freqs[i];
                         b = s->sample_rate;
                         pos = ((block_len * 2 * a) + (b << 1)) / (4 * b);
                         pos <<= 2;
diff --git a/libavcodec/wmadata.h b/libavcodec/wmadata.h
index 0a26ea4..4b56b2f 100644
--- a/libavcodec/wmadata.h
+++ b/libavcodec/wmadata.h
@@ -30,7 +30,7 @@
 #include <stdint.h>
 #include "wma.h"
 
-static const uint16_t wma_critical_freqs[25] = {
+const uint16_t ff_wma_critical_freqs[25] = {
     100,   200,  300, 400,   510,  630,  770,    920,
     1080, 1270, 1480, 1720, 2000, 2320, 2700,   3150,
     3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500,
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 89b6ce2..4aa7ddc 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -31,6 +31,7 @@ OBJS-$(CONFIG_AVM2_MUXER)                += swfenc.o
 OBJS-$(CONFIG_AVS_DEMUXER)               += avs.o vocdec.o voc.o
 OBJS-$(CONFIG_BETHSOFTVID_DEMUXER)       += bethsoftvid.o
 OBJS-$(CONFIG_BFI_DEMUXER)               += bfi.o
+OBJS-$(CONFIG_BINK_DEMUXER)              += bink.o
 OBJS-$(CONFIG_C93_DEMUXER)               += c93.o vocdec.o voc.o
 OBJS-$(CONFIG_CAVSVIDEO_DEMUXER)         += raw.o
 OBJS-$(CONFIG_CRC_MUXER)                 += crcenc.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index d80d37a..e81fc84 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -64,6 +64,7 @@ void av_register_all(void)
     REGISTER_DEMUXER  (AVS, avs);
     REGISTER_DEMUXER  (BETHSOFTVID, bethsoftvid);
     REGISTER_DEMUXER  (BFI, bfi);
+    REGISTER_DEMUXER  (BINK, bink);
     REGISTER_DEMUXER  (C93, c93);
     REGISTER_DEMUXER  (CAVSVIDEO, cavsvideo);
     REGISTER_MUXER    (CRC, crc);
diff --git a/libavformat/bink.c b/libavformat/bink.c
new file mode 100644
index 0000000..8e8436a
--- /dev/null
+++ b/libavformat/bink.c
@@ -0,0 +1,248 @@
+/*
+ * Bink file demuxer
+ * Copyright (c) 2008-2009 Peter Ross (pross at xvid.org)
+ * Copyright (c) 2009 Daniel Verkamp (daniel at drv.nu)
+ *
+ * This file is part of FFmpeg.
+ *
+ * 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.
+ *
+ * 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
+ */
+
+/**
+ * @file libavformat/bink.c
+ *
+ * Technical details here:
+ *  http://wiki.multimedia.cx/index.php?title=Bink_Container
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+
+enum BinkAudFlags {
+    BINK_AUD_16BITS = 0x4000, ///< prefer 16-bit output
+    BINK_AUD_STEREO = 0x2000,
+    BINK_AUD_USEDCT = 0x1000,
+};
+
+#define BINK_EXTRADATA_SIZE     1
+#define BINK_MAX_AUDIO_TRACKS   256
+#define BINK_MAX_WIDTH          7680
+#define BINK_MAX_HEIGHT         4800
+
+typedef struct {
+    uint32_t file_size;
+
+    uint32_t num_audio_tracks;
+    int current_track;      ///< audio track to return in next packet
+    int64_t video_pts;
+    int64_t audio_pts[BINK_MAX_AUDIO_TRACKS];
+
+    uint32_t remain_packet_size;
+} BinkDemuxContext;
+
+static int probe(AVProbeData *p)
+{
+    const uint8_t *b = p->buf;
+
+    if (b[0] == 'B' && b[1] == 'I' && b[2] == 'K' &&
+        (b[3] == 'b' || b[3] == 'f' || b[3] == 'g' || b[3] == 'h' || b[3] == 'i') &&
+        AV_RL32(b+8) > 0 &&  // num_frames
+        AV_RL32(b+20) > 0 && AV_RL32(b+20) <= BINK_MAX_WIDTH &&
+        AV_RL32(b+24) > 0 && AV_RL32(b+24) <= BINK_MAX_HEIGHT &&
+        AV_RL32(b+28) > 0 && AV_RL32(b+32) > 0)  // fps num,den
+        return AVPROBE_SCORE_MAX;
+    return 0;
+}
+
+static int read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+    BinkDemuxContext *bink = s->priv_data;
+    ByteIOContext *pb = s->pb;
+    uint32_t fps_num, fps_den;
+    AVStream *vst, *ast;
+    unsigned int i;
+    uint32_t pos, prev_pos;
+    uint16_t flags;
+    int keyframe;
+
+    vst = av_new_stream(s, 0);
+    if (!vst)
+        return AVERROR(ENOMEM);
+
+    vst->codec->codec_tag = get_le32(pb);
+
+    bink->file_size = get_le32(pb) + 8;
+    vst->duration = get_le32(pb);
+
+    if (vst->duration > 1000000) {
+        av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n");
+        return AVERROR(EIO);
+    }
+
+    if (get_le32(pb) > bink->file_size) {
+        av_log(s, AV_LOG_ERROR,
+               "invalid header: largest frame size greater than file size\n");
+        return AVERROR(EIO);
+    }
+
+    url_fskip(pb, 4);
+
+    vst->codec->width  = get_le32(pb);
+    vst->codec->height = get_le32(pb);
+
+    fps_num = get_le32(pb);
+    fps_den = get_le32(pb);
+    if (fps_num == 0 || fps_den == 0) {
+        av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%d/%d)\n", fps_num, fps_den);
+        return AVERROR(EIO);
+    }
+    av_set_pts_info(vst, 64, fps_den, fps_num);
+
+    /* video flags */
+    vst->codec->extradata_size = 4;
+    vst->codec->extradata = av_malloc(4);
+    get_buffer(pb, vst->codec->extradata, 4);
+
+    vst->codec->codec_type = CODEC_TYPE_VIDEO;
+    vst->codec->codec_id   = CODEC_ID_BINKVIDEO;
+    bink->num_audio_tracks = get_le32(pb);
+
+    if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) {
+        av_log(s, AV_LOG_ERROR,
+               "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%d)\n",
+               bink->num_audio_tracks);
+        return AVERROR(EIO);
+    }
+
+    if (bink->num_audio_tracks) {
+        url_fskip(pb, 4 * bink->num_audio_tracks);
+
+        for (i = 0; i < bink->num_audio_tracks; i++) {
+            ast = av_new_stream(s, 1);
+            if (!ast)
+                return AVERROR(ENOMEM);
+            ast->codec->codec_type  = CODEC_TYPE_AUDIO;
+            ast->codec->codec_tag   = 0;
+            ast->codec->sample_rate = get_le16(pb);
+            av_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
+            flags = get_le16(pb);
+            ast->codec->codec_id = flags & BINK_AUD_USEDCT ?
+                                   CODEC_ID_BINKAUDIO2 : CODEC_ID_BINKAUDIO1;
+            ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1;
+        }
+
+        url_fskip(pb, 4 * bink->num_audio_tracks);
+    }
+
+    /* frame index table */
+    pos = get_le32(pb) & ~1;
+    for (i = 0; i < vst->duration; i++) {
+        prev_pos = pos;
+        if (i == vst->duration - 1) {
+            pos = bink->file_size;
+            keyframe = 0;
+        } else {
+            pos = get_le32(pb);
+            keyframe = pos & 1;
+            pos &= ~1;
+        }
+        if (pos <= prev_pos) {
+            av_log(s, AV_LOG_ERROR, "invalid frame index table\n");
+            return AVERROR(EIO);
+        }
+        av_add_index_entry(vst, pos, i, pos - prev_pos, 0,
+                           keyframe ? AVINDEX_KEYFRAME : 0);
+    }
+
+    url_fskip(pb, 4);
+
+    bink->current_track = -1;
+    return 0;
+}
+
+static int read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    BinkDemuxContext *bink = s->priv_data;
+    ByteIOContext *pb = s->pb;
+    int ret;
+
+    if (bink->current_track < 0) {
+        int index_entry;
+        AVStream *st = s->streams[0]; // stream 0 is video stream with index
+
+        if (bink->video_pts >= st->duration)
+            return AVERROR(EIO);
+
+        index_entry = av_index_search_timestamp(st, bink->video_pts,
+                                                AVSEEK_FLAG_ANY);
+        if (index_entry < 0) {
+            av_log(s, AV_LOG_ERROR,
+                   "could not find index entry for frame %"PRId64"\n",
+                   bink->video_pts);
+            return AVERROR(EIO);
+        }
+
+        bink->remain_packet_size = st->index_entries[index_entry].size;
+        bink->current_track = 0;
+    }
+
+    if (bink->current_track < bink->num_audio_tracks) {
+        uint32_t audio_size = get_le32(pb);
+        if (audio_size > bink->remain_packet_size - 4) {
+            av_log(s, AV_LOG_ERROR,
+                   "frame %"PRId64": audio size in header (%u) > size of packet left (%u)\n",
+                   bink->video_pts, audio_size, bink->remain_packet_size);
+            return AVERROR(EIO);
+        }
+        bink->remain_packet_size -= 4 + audio_size;
+        bink->current_track++;
+        if (audio_size > 0) {
+            /* Each audio packet reports the number of decompressed samples
+               (in bytes). We use this value to calcuate the audio PTS */
+            int reported_size = get_le32(pb) / (2 * s->streams[bink->current_track]->codec->channels);
+            url_fseek(pb, -4, SEEK_CUR);
+
+            /* get one audio packet per track */
+            if ((ret = av_get_packet(pb, pkt, audio_size))
+                                           != audio_size)
+                return ret;
+            pkt->stream_index = bink->current_track;
+            pkt->pts = bink->audio_pts[bink->current_track - 1] += reported_size;
+            return 0;
+        }
+    }
+
+    /* get video packet */
+    if ((ret = av_get_packet(pb, pkt, bink->remain_packet_size))
+                                   != bink->remain_packet_size)
+        return ret;
+    pkt->stream_index = 0;
+    pkt->pts = bink->video_pts++;
+    pkt->flags |= PKT_FLAG_KEY;
+
+    /* -1 instructs the next call to read_packet() to read the next frame */
+    bink->current_track = -1;
+
+    return 0;
+}
+
+AVInputFormat bink_demuxer = {
+    "bink",
+    "Bink",
+    sizeof(BinkDemuxContext),
+    probe,
+    read_header,
+    read_packet,
+};
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index 7d0a8d5..d8e4a0d 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -172,12 +172,20 @@ static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap)
     /* handle possible audio streams */
     for(i = 0; i < 7; i++) {
         smk->indexes[i] = -1;
-        if((smk->rates[i] & 0xFFFFFF) && !(smk->rates[i] & SMK_AUD_BINKAUD)){
+        if(smk->rates[i] & 0xFFFFFF){
             ast[i] = av_new_stream(s, 0);
             smk->indexes[i] = ast[i]->index;
             ast[i]->codec->codec_type = CODEC_TYPE_AUDIO;
-            ast[i]->codec->codec_id = (smk->rates[i] & SMK_AUD_PACKED) ? CODEC_ID_SMACKAUDIO : CODEC_ID_PCM_U8;
-            ast[i]->codec->codec_tag = MKTAG('S', 'M', 'K', 'A');
+            if (smk->rates[i] & (SMK_AUD_BINKAUD | SMK_AUD_USEDCT)) {
+                ast[i]->codec->codec_id = smk->rates[i] & SMK_AUD_USEDCT ?
+                                          CODEC_ID_BINKAUDIO2 : CODEC_ID_BINKAUDIO1;
+                ast[i]->codec->codec_tag = 0;
+            } else if (smk->rates[i] & SMK_AUD_PACKED) {
+                ast[i]->codec->codec_id = CODEC_ID_SMACKAUDIO;
+                ast[i]->codec->codec_tag = MKTAG('S', 'M', 'K', 'A');
+            } else {
+                ast[i]->codec->codec_id = CODEC_ID_PCM_U8;
+            }
             ast[i]->codec->channels = (smk->rates[i] & SMK_AUD_STEREO) ? 2 : 1;
             ast[i]->codec->sample_rate = smk->rates[i] & 0xFFFFFF;
             ast[i]->codec->bits_per_coded_sample = (smk->rates[i] & SMK_AUD_16BITS) ? 16 : 8;



More information about the ffmpeg-devel mailing list