/*
 * Copyright (C) 2003-2004 The FFmpeg project
 * Copyright (C) 2019 Peter Ross
 *
 * 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
 * On2 VP3/VP4 Video Decoder
 *
 * VP3 Video Decoder by Mike Melanson (mike at multimedia.cx)
 * For more information about the VP3 coding process, visit:
 *   http://wiki.multimedia.cx/index.php?title=On2_VP3
 *
 * Theora decoder by Alex Beregszaszi
 */

#include "config_components.h"

#include <stddef.h>
#include <string.h>

#include "libavutil/emms.h"
#include "libavutil/imgutils.h"
#include "libavutil/mem.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"

#include "avcodec.h"
#include "codec_internal.h"
#include "decode.h"
#include "get_bits.h"
#include "hpeldsp.h"
#include "internal.h"
#include "jpegquanttables.h"
#include "mathops.h"
#include "progressframe.h"
#include "refstruct.h"
#include "thread.h"
#include "videodsp.h"
#include "vp3data.h"
#include "vp4data.h"
#include "vp3dsp.h"
#include "xiph.h"

#define VP3_MV_VLC_BITS     6
#define VP4_MV_VLC_BITS     6
#define SUPERBLOCK_VLC_BITS 6

#define FRAGMENT_PIXELS 8

// FIXME split things out into their own arrays
typedef struct Vp3Fragment {
    int16_t dc;
    uint8_t coding_method;
    uint8_t qpi;
} Vp3Fragment;

#define SB_NOT_CODED        0
#define SB_PARTIALLY_CODED  1
#define SB_FULLY_CODED      2

// This is the maximum length of a single long bit run that can be encoded
// for superblock coding or block qps. Theora special-cases this to read a
// bit instead of flipping the current bit to allow for runs longer than 4129.
#define MAXIMUM_LONG_BIT_RUN 4129

#define MODE_INTER_NO_MV      0
#define MODE_INTRA            1
#define MODE_INTER_PLUS_MV    2
#define MODE_INTER_LAST_MV    3
#define MODE_INTER_PRIOR_LAST 4
#define MODE_USING_GOLDEN     5
#define MODE_GOLDEN_MV        6
#define MODE_INTER_FOURMV     7
#define CODING_MODE_COUNT     8

/* special internal mode */
#define MODE_COPY             8

static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb);
static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb);


/* There are 6 preset schemes, plus a free-form scheme */
static const int ModeAlphabet[6][CODING_MODE_COUNT] = {
    /* scheme 1: Last motion vector dominates */
    { MODE_INTER_LAST_MV,    MODE_INTER_PRIOR_LAST,
      MODE_INTER_PLUS_MV,    MODE_INTER_NO_MV,
      MODE_INTRA,            MODE_USING_GOLDEN,
      MODE_GOLDEN_MV,        MODE_INTER_FOURMV },

    /* scheme 2 */
    { MODE_INTER_LAST_MV,    MODE_INTER_PRIOR_LAST,
      MODE_INTER_NO_MV,      MODE_INTER_PLUS_MV,
      MODE_INTRA,            MODE_USING_GOLDEN,
      MODE_GOLDEN_MV,        MODE_INTER_FOURMV },

    /* scheme 3 */
    { MODE_INTER_LAST_MV,    MODE_INTER_PLUS_MV,
      MODE_INTER_PRIOR_LAST, MODE_INTER_NO_MV,
      MODE_INTRA,            MODE_USING_GOLDEN,
      MODE_GOLDEN_MV,        MODE_INTER_FOURMV },

    /* scheme 4 */
    { MODE_INTER_LAST_MV,    MODE_INTER_PLUS_MV,
      MODE_INTER_NO_MV,      MODE_INTER_PRIOR_LAST,
      MODE_INTRA,            MODE_USING_GOLDEN,
      MODE_GOLDEN_MV,        MODE_INTER_FOURMV },

    /* scheme 5: No motion vector dominates */
    { MODE_INTER_NO_MV,      MODE_INTER_LAST_MV,
      MODE_INTER_PRIOR_LAST, MODE_INTER_PLUS_MV,
      MODE_INTRA,            MODE_USING_GOLDEN,
      MODE_GOLDEN_MV,        MODE_INTER_FOURMV },

    /* scheme 6 */
    { MODE_INTER_NO_MV,      MODE_USING_GOLDEN,
      MODE_INTER_LAST_MV,    MODE_INTER_PRIOR_LAST,
      MODE_INTER_PLUS_MV,    MODE_INTRA,
      MODE_GOLDEN_MV,        MODE_INTER_FOURMV },
};

static const uint8_t hilbert_offset[16][2] = {
    { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 },
    { 0, 2 }, { 0, 3 }, { 1, 3 }, { 1, 2 },
    { 2, 2 }, { 2, 3 }, { 3, 3 }, { 3, 2 },
    { 3, 1 }, { 2, 1 }, { 2, 0 }, { 3, 0 }
};

enum {
    VP4_DC_INTRA  = 0,
    VP4_DC_INTER  = 1,
    VP4_DC_GOLDEN = 2,
    NB_VP4_DC_TYPES,
    VP4_DC_UNDEFINED = NB_VP4_DC_TYPES
};

static const uint8_t vp4_pred_block_type_map[8] = {
    [MODE_INTER_NO_MV]      = VP4_DC_INTER,
    [MODE_INTRA]            = VP4_DC_INTRA,
    [MODE_INTER_PLUS_MV]    = VP4_DC_INTER,
    [MODE_INTER_LAST_MV]    = VP4_DC_INTER,
    [MODE_INTER_PRIOR_LAST] = VP4_DC_INTER,
    [MODE_USING_GOLDEN]     = VP4_DC_GOLDEN,
    [MODE_GOLDEN_MV]        = VP4_DC_GOLDEN,
    [MODE_INTER_FOURMV]     = VP4_DC_INTER,
};

static VLCElem superblock_run_length_vlc[88]; /* version <  2 */
static VLCElem fragment_run_length_vlc[56];   /* version <  2 */
static VLCElem motion_vector_vlc[112];        /* version <  2 */

// The VP4 tables reuse this vlc.
static VLCElem mode_code_vlc[24 + 2108 * CONFIG_VP4_DECODER];

#if CONFIG_VP4_DECODER
static const VLCElem *vp4_mv_vlc_table[2][7]; /* version >= 2 */
static const VLCElem *block_pattern_vlc[2];   /* version >= 2 */
#endif

typedef struct {
    int dc;
    int type;
} VP4Predictor;

#define MIN_DEQUANT_VAL 2

typedef struct HuffEntry {
    uint8_t len, sym;
} HuffEntry;

typedef struct HuffTable {
    HuffEntry entries[32];
    uint8_t   nb_entries;
} HuffTable;

typedef struct CoeffVLCs {
    const VLCElem *vlc_tabs[80];
    VLC vlcs[80];
} CoeffVLCs;

typedef struct Vp3DecodeContext {
    AVCodecContext *avctx;
    int theora, theora_tables, theora_header;
    int version;
    int width, height;
    int chroma_x_shift, chroma_y_shift;
    ProgressFrame golden_frame;
    ProgressFrame last_frame;
    ProgressFrame current_frame;
    int keyframe;
    uint8_t idct_permutation[64];
    uint8_t idct_scantable[64];
    HpelDSPContext hdsp;
    VideoDSPContext vdsp;
    VP3DSPContext vp3dsp;
    DECLARE_ALIGNED(16, int16_t, block)[64];
    int flipped_image;
    int last_slice_end;
    int skip_loop_filter;

    int qps[3];
    int nqps;
    int last_qps[3];

    int superblock_count;
    int y_superblock_width;
    int y_superblock_height;
    int y_superblock_count;
    int c_superblock_width;
    int c_superblock_height;
    int c_superblock_count;
    int u_superblock_start;
    int v_superblock_start;
    unsigned char *superblock_coding;

    int macroblock_count; /* y macroblock count */
    int macroblock_width;
    int macroblock_height;
    int c_macroblock_count;
    int c_macroblock_width;
    int c_macroblock_height;
    int yuv_macroblock_count; /* y+u+v macroblock count */

    int fragment_count;
    int fragment_width[2];
    int fragment_height[2];

    Vp3Fragment *all_fragments;
    int fragment_start[3];
    int data_offset[3];
    uint8_t offset_x;
    uint8_t offset_y;
    int offset_x_warned;

    int8_t (*motion_val[2])[2];

    /* tables */
    uint16_t coded_dc_scale_factor[2][64];
    uint32_t coded_ac_scale_factor[64];
    uint8_t base_matrix[384][64];
    uint8_t qr_count[2][3];
    uint8_t qr_size[2][3][64];
    uint16_t qr_base[2][3][64];

    /**
     * This is a list of all tokens in bitstream order. Reordering takes place
     * by pulling from each level during IDCT. As a consequence, IDCT must be
     * in Hilbert order, making the minimum slice height 64 for 4:2:0 and 32
     * otherwise. The 32 different tokens with up to 12 bits of extradata are
     * collapsed into 3 types, packed as follows:
     *   (from the low to high bits)
     *
     * 2 bits: type (0,1,2)
     *   0: EOB run, 14 bits for run length (12 needed)
     *   1: zero run, 7 bits for run length
     *                7 bits for the next coefficient (3 needed)
     *   2: coefficient, 14 bits (11 needed)
     *
     * Coefficients are signed, so are packed in the highest bits for automatic
     * sign extension.
     */
    int16_t *dct_tokens[3][64];
    int16_t *dct_tokens_base;
#define TOKEN_EOB(eob_run)              ((eob_run) << 2)
#define TOKEN_ZERO_RUN(coeff, zero_run) (((coeff) * 512) + ((zero_run) << 2) + 1)
#define TOKEN_COEFF(coeff)              (((coeff) * 4) + 2)

    /**
     * number of blocks that contain DCT coefficients at
     * the given level or higher
     */
    int num_coded_frags[3][64];
    int total_num_coded_frags;

    /* this is a list of indexes into the all_fragments array indicating
     * which of the fragments are coded */
    int *coded_fragment_list[3];

    int *kf_coded_fragment_list;
    int *nkf_coded_fragment_list;
    int num_kf_coded_fragment[3];

    /**
     * The first 16 of the following VLCs are for the dc coefficients;
     * the others are four groups of 16 VLCs each for ac coefficients.
     * This is a RefStruct reference to share these VLCs between threads.
     */
    CoeffVLCs *coeff_vlc;

    /* these arrays need to be on 16-byte boundaries since SSE2 operations
     * index into them */
    DECLARE_ALIGNED(16, int16_t, qmat)[3][2][3][64];     ///< qmat[qpi][is_inter][plane]

    /* This table contains superblock_count * 16 entries. Each set of 16
     * numbers corresponds to the fragment indexes 0..15 of the superblock.
     * An entry will be -1 to indicate that no entry corresponds to that
     * index. */
    int *superblock_fragments;

    /* This is an array that indicates how a particular macroblock
     * is coded. */
    unsigned char *macroblock_coding;

    uint8_t *edge_emu_buffer;

    /* Huffman decode */
    HuffTable huffman_table[5 * 16];

    uint8_t filter_limit_values[64];
    DECLARE_ALIGNED(8, int, bounding_values_array)[256 + 2];

    VP4Predictor * dc_pred_row; /* dc_pred_row[y_superblock_width * 4] */
} Vp3DecodeContext;

/************************************************************************
 * VP3 specific functions
 ************************************************************************/

static av_cold void free_tables(AVCodecContext *avctx)
{
    Vp3DecodeContext *s = avctx->priv_data;

    av_freep(&s->superblock_coding);
    av_freep(&s->all_fragments);
    av_freep(&s->nkf_coded_fragment_list);
    av_freep(&s->kf_coded_fragment_list);
    av_freep(&s->dct_tokens_base);
    av_freep(&s->superblock_fragments);
    av_freep(&s->macroblock_coding);
    av_freep(&s->dc_pred_row);
    av_freep(&s->motion_val[0]);
    av_freep(&s->motion_val[1]);
}

static void vp3_decode_flush(AVCodecContext *avctx)
{
    Vp3DecodeContext *s = avctx->priv_data;

    ff_progress_frame_unref(&s->golden_frame);
    ff_progress_frame_unref(&s->last_frame);
    ff_progress_frame_unref(&s->current_frame);
}

static av_cold int vp3_decode_end(AVCodecContext *avctx)
{
    Vp3DecodeContext *s = avctx->priv_data;

    free_tables(avctx);
    av_freep(&s->edge_emu_buffer);

    s->theora_tables = 0;

    /* release all frames */
    vp3_decode_flush(avctx);

    ff_refstruct_unref(&s->coeff_vlc);

    return 0;
}

/**
 * This function sets up all of the various blocks mappings:
 * superblocks <-> fragments, macroblocks <-> fragments,
 * superblocks <-> macroblocks
 *
 * @return 0 is successful; returns 1 if *anything* went wrong.
 */
static int init_block_mapping(Vp3DecodeContext *s)
{
    int j = 0;

    for (int plane = 0; plane < 3; plane++) {
        int sb_width    = plane ? s->c_superblock_width
                                : s->y_superblock_width;
        int sb_height   = plane ? s->c_superblock_height
                                : s->y_superblock_height;
        int frag_width  = s->fragment_width[!!plane];
        int frag_height = s->fragment_height[!!plane];

        for (int sb_y = 0; sb_y < sb_height; sb_y++)
            for (int sb_x = 0; sb_x < sb_width; sb_x++)
                for (int i = 0; i < 16; i++) {
                    int x = 4 * sb_x + hilbert_offset[i][0];
                    int y = 4 * sb_y + hilbert_offset[i][1];

                    if (x < frag_width && y < frag_height)
                        s->superblock_fragments[j++] = s->fragment_start[plane] +
                                                       y * frag_width + x;
                    else
                        s->superblock_fragments[j++] = -1;
                }
    }

    return 0;  /* successful path out */
}

/*
 * This function sets up the dequantization tables used for a particular
 * frame.
 */
static void init_dequantizer(Vp3DecodeContext *s, int qpi)
{
    int ac_scale_factor = s->coded_ac_scale_factor[s->qps[qpi]];

    for (int inter = 0; inter < 2; inter++) {
        for (int plane = 0; plane < 3; plane++) {
            int dc_scale_factor = s->coded_dc_scale_factor[!!plane][s->qps[qpi]];
            int sum = 0, bmi, bmj, qistart, qri;
            for (qri = 0; qri < s->qr_count[inter][plane]; qri++) {
                sum += s->qr_size[inter][plane][qri];
                if (s->qps[qpi] <= sum)
                    break;
            }
            qistart = sum - s->qr_size[inter][plane][qri];
            bmi     = s->qr_base[inter][plane][qri];
            bmj     = s->qr_base[inter][plane][qri + 1];
            for (int i = 0; i < 64; i++) {
                int coeff = (2 * (sum     - s->qps[qpi]) * s->base_matrix[bmi][i] -
                             2 * (qistart - s->qps[qpi]) * s->base_matrix[bmj][i] +
                             s->qr_size[inter][plane][qri]) /
                            (2 * s->qr_size[inter][plane][qri]);

                int qmin   = 8 << (inter + !i);
                int qscale = i ? ac_scale_factor : dc_scale_factor;
                int qbias = (1 + inter) * 3;
                s->qmat[qpi][inter][plane][s->idct_permutation[i]] =
                    (i == 0 || s->version < 2) ? av_clip((qscale * coeff) / 100 * 4, qmin, 4096)
                                               : (qscale * (coeff - qbias) / 100 + qbias) * 4;
            }
            /* all DC coefficients use the same quant so as not to interfere
             * with DC prediction */
            s->qmat[qpi][inter][plane][0] = s->qmat[0][inter][plane][0];
        }
    }
}

/*
 * This function initializes the loop filter boundary limits if the frame's
 * quality index is different from the previous frame's.
 *
 * The filter_limit_values may not be larger than 127.
 */
static void init_loop_filter(Vp3DecodeContext *s)
{
    ff_vp3dsp_set_bounding_values(s->bounding_values_array, s->filter_limit_values[s->qps[0]]);
}

/*
 * This function unpacks all of the superblock/macroblock/fragment coding
 * information from the bitstream.
 */
static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
{
    const int superblock_starts[3] = {
        0, s->u_superblock_start, s->v_superblock_start
    };
    int bit = 0;
    int current_superblock = 0;
    int current_run = 0;
    int num_partial_superblocks = 0;

    int current_fragment;
    int plane0_num_coded_frags = 0;

    if (s->keyframe) {
        memset(s->superblock_coding, SB_FULLY_CODED, s->superblock_count);
    } else {
        /* unpack the list of partially-coded superblocks */
        bit         = get_bits1(gb) ^ 1;
        current_run = 0;

        while (current_superblock < s->superblock_count && get_bits_left(gb) > 0) {
            if (s->theora && current_run == MAXIMUM_LONG_BIT_RUN)
                bit = get_bits1(gb);
            else
                bit ^= 1;

            current_run = get_vlc2(gb, superblock_run_length_vlc,
                                   SUPERBLOCK_VLC_BITS, 2);
            if (current_run == 34)
                current_run += get_bits(gb, 12);

            if (current_run > s->superblock_count - current_superblock) {
                av_log(s->avctx, AV_LOG_ERROR,
                       "Invalid partially coded superblock run length\n");
                return -1;
            }

            memset(s->superblock_coding + current_superblock, bit, current_run);

            current_superblock += current_run;
            if (bit)
                num_partial_superblocks += current_run;
        }

        /* unpack the list of fully coded superblocks if any of the blocks were
         * not marked as partially coded in the previous step */
        if (num_partial_superblocks < s->superblock_count) {
            int superblocks_decoded = 0;

            current_superblock = 0;
            bit                = get_bits1(gb) ^ 1;
            current_run        = 0;

            while (superblocks_decoded < s->superblock_count - num_partial_superblocks &&
                   get_bits_left(gb) > 0) {
                if (s->theora && current_run == MAXIMUM_LONG_BIT_RUN)
                    bit = get_bits1(gb);
                else
                    bit ^= 1;

                current_run = get_vlc2(gb, superblock_run_length_vlc,
                                       SUPERBLOCK_VLC_BITS, 2);
                if (current_run == 34)
                    current_run += get_bits(gb, 12);

                for (int j = 0; j < current_run; current_superblock++) {
                    if (current_superblock >= s->superblock_count) {
                        av_log(s->avctx, AV_LOG_ERROR,
                               "Invalid fully coded superblock run length\n");
                        return -1;
                    }

                    /* skip any superblocks already marked as partially coded */
                    if (s->superblock_coding[current_superblock] == SB_NOT_CODED) {
                        s->superblock_coding[current_superblock] = 2 * bit;
                        j++;
                    }
                }
                superblocks_decoded += current_run;
            }
        }

        /* if there were partial blocks, initialize bitstream for
         * unpacking fragment codings */
        if (num_partial_superblocks) {
            current_run = 0;
            bit         = get_bits1(gb);
            /* toggle the bit because as soon as the first run length is
             * fetched the bit will be toggled again */
            bit ^= 1;
        }
    }

    /* figure out which fragments are coded; iterate through each
     * superblock (all planes) */
    s->total_num_coded_frags = 0;
    memset(s->macroblock_coding, MODE_COPY, s->macroblock_count);

    s->coded_fragment_list[0] = s->keyframe ? s->kf_coded_fragment_list
                                            : s->nkf_coded_fragment_list;

    for (int plane = 0; plane < 3; plane++) {
        int sb_start = superblock_starts[plane];
        int sb_end   = sb_start + (plane ? s->c_superblock_count
                                         : s->y_superblock_count);
        int num_coded_frags = 0;

        if (s->keyframe) {
            if (s->num_kf_coded_fragment[plane] == -1) {
                for (int i = sb_start; i < sb_end; i++) {
                    /* iterate through all 16 fragments in a superblock */
                    for (int j = 0; j < 16; j++) {
                        /* if the fragment is in bounds, check its coding status */
                        current_fragment = s->superblock_fragments[i * 16 + j];
                        if (current_fragment != -1) {
                            s->coded_fragment_list[plane][num_coded_frags++] =
                                current_fragment;
                        }
                    }
                }
                s->num_kf_coded_fragment[plane] = num_coded_frags;
            } else
                num_coded_frags = s->num_kf_coded_fragment[plane];
        } else {
            for (int i = sb_start; i < sb_end && get_bits_left(gb) > 0; i++) {
                if (get_bits_left(gb) < plane0_num_coded_frags >> 2) {
                    return AVERROR_INVALIDDATA;
                }
                /* iterate through all 16 fragments in a superblock */
                for (int j = 0; j < 16; j++) {
                    /* if the fragment is in bounds, check its coding status */
                    current_fragment = s->superblock_fragments[i * 16 + j];
                    if (current_fragment != -1) {
                        int coded = s->superblock_coding[i];

                        if (coded == SB_PARTIALLY_CODED) {
                            /* fragment may or may not be coded; this is the case
                             * that cares about the fragment coding runs */
                            if (current_run-- == 0) {
                                bit        ^= 1;
                                current_run = get_vlc2(gb, fragment_run_length_vlc, 5, 2);
                            }
                            coded = bit;
                        }

                        if (coded) {
                            /* default mode; actual mode will be decoded in
                             * the next phase */
                            s->all_fragments[current_fragment].coding_method =
                                MODE_INTER_NO_MV;
                            s->coded_fragment_list[plane][num_coded_frags++] =
                                current_fragment;
                        } else {
                            /* not coded; copy this fragment from the prior frame */
                            s->all_fragments[current_fragment].coding_method =
                                MODE_COPY;
                        }
                    }
                }
            }
        }
        if (!plane)
            plane0_num_coded_frags = num_coded_frags;
        s->total_num_coded_frags += num_coded_frags;
        for (int i = 0; i < 64; i++)
            s->num_coded_frags[plane][i] = num_coded_frags;
        if (plane < 2)
            s->coded_fragment_list[plane + 1] = s->coded_fragment_list[plane] +
                                                num_coded_frags;
    }
    return 0;
}

#define BLOCK_X (2 * mb_x + (k & 1))
#define BLOCK_Y (2 * mb_y + (k >> 1))

#if CONFIG_VP4_DECODER
/**
 * @return number of blocks, or > yuv_macroblock_count on error.
 *         return value is always >= 1.
 */
static int vp4_get_mb_count(Vp3DecodeContext *s, GetBitContext *gb)
{
    int v = 1;
    int bits;
    while ((bits = show_bits(gb, 9)) == 0x1ff) {
        skip_bits(gb, 9);
        v += 256;
        if (v > s->yuv_macroblock_count) {
            av_log(s->avctx, AV_LOG_ERROR, "Invalid run length\n");
            return v;
        }
    }
#define body(n) { \
    skip_bits(gb, 2 + n); \
    v += (1 << n) + get_bits(gb, n); }
#define thresh(n) (0x200 - (0x80 >> n))
#define else_if(n) else if (bits < thresh(n)) body(n)
    if (bits < 0x100) {
        skip_bits(gb, 1);
    } else if (bits < thresh(0)) {
        skip_bits(gb, 2);
        v += 1;
    }
    else_if(1)
    else_if(2)
    else_if(3)
    else_if(4)
    else_if(5)
    else_if(6)
    else body(7)
#undef body
#undef thresh
#undef else_if
    return v;
}

static int vp4_get_block_pattern(GetBitContext *gb, int *next_block_pattern_table)
{
    int v = get_vlc2(gb, block_pattern_vlc[*next_block_pattern_table], 5, 1);
    *next_block_pattern_table = vp4_block_pattern_table_selector[v];
    return v + 1;
}

static int vp4_unpack_macroblocks(Vp3DecodeContext *s, GetBitContext *gb)
{
    int fragment;
    int next_block_pattern_table;
    int bit, current_run, has_partial;

    memset(s->macroblock_coding, MODE_COPY, s->macroblock_count);

    if (s->keyframe)
        return 0;

    has_partial = 0;
    bit         = get_bits1(gb);
    for (int i = 0; i < s->yuv_macroblock_count; i += current_run) {
        if (get_bits_left(gb) <= 0)
            return AVERROR_INVALIDDATA;
        current_run = vp4_get_mb_count(s, gb);
        if (current_run > s->yuv_macroblock_count - i)
            return -1;
        memset(s->superblock_coding + i, 2 * bit, current_run);
        bit ^= 1;
        has_partial |= bit;
    }

    if (has_partial) {
        if (get_bits_left(gb) <= 0)
            return AVERROR_INVALIDDATA;
        bit  = get_bits1(gb);
        current_run = vp4_get_mb_count(s, gb);
        for (int i = 0; i < s->yuv_macroblock_count; i++) {
            if (!s->superblock_coding[i]) {
                if (!current_run) {
                    bit ^= 1;
                    current_run = vp4_get_mb_count(s, gb);
                }
                s->superblock_coding[i] = bit;
                current_run--;
            }
        }
        if (current_run) /* handle situation when vp4_get_mb_count() fails */
            return -1;
    }

    next_block_pattern_table = 0;
    for (int plane = 0, i = 0; plane < 3; plane++) {
        int sb_width = plane ? s->c_superblock_width : s->y_superblock_width;
        int sb_height = plane ? s->c_superblock_height : s->y_superblock_height;
        int mb_width = plane ? s->c_macroblock_width : s->macroblock_width;
        int mb_height = plane ? s->c_macroblock_height : s->macroblock_height;
        int fragment_width = s->fragment_width[!!plane];
        int fragment_height = s->fragment_height[!!plane];

        for (int sb_y = 0; sb_y < sb_height; sb_y++) {
            for (int sb_x = 0; sb_x < sb_width; sb_x++) {
                for (int j = 0; j < 4; j++) {
                    int mb_x = 2 * sb_x + (j >> 1);
                    int mb_y = 2 * sb_y + (j >> 1) ^ (j & 1);
                    int mb_coded, pattern, coded;

                    if (mb_x >= mb_width || mb_y >= mb_height)
                        continue;

                    mb_coded = s->superblock_coding[i++];

                    if (mb_coded == SB_FULLY_CODED)
                        pattern = 0xF;
                    else if (mb_coded == SB_PARTIALLY_CODED)
                        pattern = vp4_get_block_pattern(gb, &next_block_pattern_table);
                    else
                        pattern = 0;

                    for (int k = 0; k < 4; k++) {
                        if (BLOCK_X >= fragment_width || BLOCK_Y >= fragment_height)
                            continue;
                        fragment = s->fragment_start[plane] + BLOCK_Y * fragment_width + BLOCK_X;
                        coded = pattern & (8 >> k);
                        /* MODE_INTER_NO_MV is the default for coded fragments.
                           the actual method is decoded in the next phase. */
                        s->all_fragments[fragment].coding_method = coded ? MODE_INTER_NO_MV : MODE_COPY;
                    }
                }
            }
        }
    }
    return 0;
}
#endif

/*
 * This function unpacks all the coding mode data for individual macroblocks
 * from the bitstream.
 */
static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb)
{
    int scheme;
    int current_macroblock;
    int current_fragment;
    int coding_mode;
    int custom_mode_alphabet[CODING_MODE_COUNT];
    const int *alphabet;
    Vp3Fragment *frag;

    if (s->keyframe) {
        for (int i = 0; i < s->fragment_count; i++)
            s->all_fragments[i].coding_method = MODE_INTRA;
    } else {
        /* fetch the mode coding scheme for this frame */
        scheme = get_bits(gb, 3);

        /* is it a custom coding scheme? */
        if (scheme == 0) {
            for (int i = 0; i < 8; i++)
                custom_mode_alphabet[i] = MODE_INTER_NO_MV;
            for (int i = 0; i < 8; i++)
                custom_mode_alphabet[get_bits(gb, 3)] = i;
            alphabet = custom_mode_alphabet;
        } else
            alphabet = ModeAlphabet[scheme - 1];

        /* iterate through all of the macroblocks that contain 1 or more
         * coded fragments */
        for (int sb_y = 0; sb_y < s->y_superblock_height; sb_y++) {
            for (int sb_x = 0; sb_x < s->y_superblock_width; sb_x++) {
                if (get_bits_left(gb) <= 0)
                    return -1;

                for (int j = 0; j < 4; j++) {
                    int k;
                    int mb_x = 2 * sb_x + (j >> 1);
                    int mb_y = 2 * sb_y + (((j >> 1) + j) & 1);
                    current_macroblock = mb_y * s->macroblock_width + mb_x;

                    if (mb_x >= s->macroblock_width ||
                        mb_y >= s->macroblock_height)
                        continue;

                    /* coding modes are only stored if the macroblock has
                     * at least one luma block coded, otherwise it must be
                     * INTER_NO_MV */
                    for (k = 0; k < 4; k++) {
                        current_fragment = BLOCK_Y *
                                           s->fragment_width[0] + BLOCK_X;
                        if (s->all_fragments[current_fragment].coding_method != MODE_COPY)
                            break;
                    }
                    if (k == 4) {
                        s->macroblock_coding[current_macroblock] = MODE_INTER_NO_MV;
                        continue;
                    }

                    /* mode 7 means get 3 bits for each coding mode */
                    if (scheme == 7)
                        coding_mode = get_bits(gb, 3);
                    else
                        coding_mode = alphabet[get_vlc2(gb, mode_code_vlc, 4, 2)];

                    s->macroblock_coding[current_macroblock] = coding_mode;
                    for (k = 0; k < 4; k++) {
                        frag = s->all_fragments + BLOCK_Y * s->fragment_width[0] + BLOCK_X;
                        if (frag->coding_method != MODE_COPY)
                            frag->coding_method = coding_mode;
                    }

#define SET_CHROMA_MODES                                                      \
    if (frag[s->fragment_start[1]].coding_method != MODE_COPY)                \
        frag[s->fragment_start[1]].coding_method = coding_mode;               \
    if (frag[s->fragment_start[2]].coding_method != MODE_COPY)                \
        frag[s->fragment_start[2]].coding_method = coding_mode;

                    if (s->chroma_y_shift) {
                        frag = s->all_fragments + mb_y *
                               s->fragment_width[1] + mb_x;
                        SET_CHROMA_MODES
                    } else if (s->chroma_x_shift) {
                        frag = s->all_fragments +
                               2 * mb_y * s->fragment_width[1] + mb_x;
                        for (k = 0; k < 2; k++) {
                            SET_CHROMA_MODES
                            frag += s->fragment_width[1];
                        }
                    } else {
                        for (k = 0; k < 4; k++) {
                            frag = s->all_fragments +
                                   BLOCK_Y * s->fragment_width[1] + BLOCK_X;
                            SET_CHROMA_MODES
                        }
                    }
                }
            }
        }
    }

    return 0;
}

static int vp4_get_mv(GetBitContext *gb, int axis, int last_motion)
{
#if CONFIG_VP4_DECODER
    int v = get_vlc2(gb, vp4_mv_vlc_table[axis][vp4_mv_table_selector[FFABS(last_motion)]],
                     VP4_MV_VLC_BITS, 2);
    return last_motion < 0 ? -v : v;
#else
    return 0;
#endif
}

/*
 * This function unpacks all the motion vectors for the individual
 * macroblocks from the bitstream.
 */
static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb)
{
    int coding_mode;
    int motion_x[4];
    int motion_y[4];
    int last_motion_x = 0;
    int last_motion_y = 0;
    int prior_last_motion_x = 0;
    int prior_last_motion_y = 0;
    int last_gold_motion_x = 0;
    int last_gold_motion_y = 0;
    int current_macroblock;
    int current_fragment;
    int frag;

    if (s->keyframe)
        return 0;

    /* coding mode 0 is the VLC scheme; 1 is the fixed code scheme; 2 is VP4 code scheme */
    coding_mode = s->version < 2 ? get_bits1(gb) : 2;

    /* iterate through all of the macroblocks that contain 1 or more
     * coded fragments */
    for (int sb_y = 0; sb_y < s->y_superblock_height; sb_y++) {
        for (int sb_x = 0; sb_x < s->y_superblock_width; sb_x++) {
            if (get_bits_left(gb) <= 0)
                return -1;

            for (int j = 0; j < 4; j++) {
                int mb_x = 2 * sb_x + (j >> 1);
                int mb_y = 2 * sb_y + (((j >> 1) + j) & 1);
                current_macroblock = mb_y * s->macroblock_width + mb_x;

                if (mb_x >= s->macroblock_width  ||
                    mb_y >= s->macroblock_height ||
                    s->macroblock_coding[current_macroblock] == MODE_COPY)
                    continue;

                switch (s->macroblock_coding[current_macroblock]) {
                case MODE_GOLDEN_MV:
                    if (coding_mode == 2) { /* VP4 */
                        last_gold_motion_x = motion_x[0] = vp4_get_mv(gb, 0, last_gold_motion_x);
                        last_gold_motion_y = motion_y[0] = vp4_get_mv(gb, 1, last_gold_motion_y);
                        break;
                    } /* otherwise fall through */
                case MODE_INTER_PLUS_MV:
                    /* all 6 fragments use the same motion vector */
                    if (coding_mode == 0) {
                        motion_x[0] = get_vlc2(gb, motion_vector_vlc,
                                               VP3_MV_VLC_BITS, 2);
                        motion_y[0] = get_vlc2(gb, motion_vector_vlc,
                                               VP3_MV_VLC_BITS, 2);
                    } else if (coding_mode == 1) {
                        motion_x[0] = fixed_motion_vector_table[get_bits(gb, 6)];
                        motion_y[0] = fixed_motion_vector_table[get_bits(gb, 6)];
                    } else { /* VP4 */
                        motion_x[0] = vp4_get_mv(gb, 0, last_motion_x);
                        motion_y[0] = vp4_get_mv(gb, 1, last_motion_y);
                    }

                    /* vector maintenance, only on MODE_INTER_PLUS_MV */
                    if (s->macroblock_coding[current_macroblock] == MODE_INTER_PLUS_MV) {
                        prior_last_motion_x = last_motion_x;
                        prior_last_motion_y = last_motion_y;
                        last_motion_x       = motion_x[0];
                        last_motion_y       = motion_y[0];
                    }
                    break;

                case MODE_INTER_FOURMV:
                    /* vector maintenance */
                    prior_last_motion_x = last_motion_x;
                    prior_last_motion_y = last_motion_y;

                    /* fetch 4 vectors from the bitstream, one for each
                     * Y fragment, then average for the C fragment vectors */
                    for (int k = 0; k < 4; k++) {
                        current_fragment = BLOCK_Y * s->fragment_width[0] + BLOCK_X;
                        if (s->all_fragments[current_fragment].coding_method != MODE_COPY) {
                            if (coding_mode == 0) {
                                motion_x[k] = get_vlc2(gb, motion_vector_vlc,
                                                       VP3_MV_VLC_BITS, 2);
                                motion_y[k] = get_vlc2(gb, motion_vector_vlc,
                                                       VP3_MV_VLC_BITS, 2);
                            } else if (coding_mode == 1) {
                                motion_x[k] = fixed_motion_vector_table[get_bits(gb, 6)];
                                motion_y[k] = fixed_motion_vector_table[get_bits(gb, 6)];
                            } else { /* VP4 */
                                motion_x[k] = vp4_get_mv(gb, 0, prior_last_motion_x);
                                motion_y[k] = vp4_get_mv(gb, 1, prior_last_motion_y);
                            }
                            last_motion_x = motion_x[k];
                            last_motion_y = motion_y[k];
                        } else {
                            motion_x[k] = 0;
                            motion_y[k] = 0;
                        }
                    }
                    break;

                case MODE_INTER_LAST_MV:
                    /* all 6 fragments use the last motion vector */
                    motion_x[0] = last_motion_x;
                    motion_y[0] = last_motion_y;

                    /* no vector maintenance (last vector remains the
                     * last vector) */
                    break;

                case MODE_INTER_PRIOR_LAST:
                    /* all 6 fragments use the motion vector prior to the
                     * last motion vector */
                    motion_x[0] = prior_last_motion_x;
                    motion_y[0] = prior_last_motion_y;

                    /* vector maintenance */
                    prior_last_motion_x = last_motion_x;
                    prior_last_motion_y = last_motion_y;
                    last_motion_x       = motion_x[0];
                    last_motion_y       = motion_y[0];
                    break;

                default:
                    /* covers intra, inter without MV, golden without MV */
                    motion_x[0] = 0;
                    motion_y[0] = 0;

                    /* no vector maintenance */
                    break;
                }

                /* assign the motion vectors to the correct fragments */
                for (int k = 0; k < 4; k++) {
                    current_fragment =
                        BLOCK_Y * s->fragment_width[0] + BLOCK_X;
                    if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
                        s->motion_val[0][current_fragment][0] = motion_x[k];
                        s->motion_val[0][current_fragment][1] = motion_y[k];
                    } else {
                        s->motion_val[0][current_fragment][0] = motion_x[0];
                        s->motion_val[0][current_fragment][1] = motion_y[0];
                    }
                }

                if (s->chroma_y_shift) {
                    if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
                        motion_x[0] = RSHIFT(motion_x[0] + motion_x[1] +
                                             motion_x[2] + motion_x[3], 2);
                        motion_y[0] = RSHIFT(motion_y[0] + motion_y[1] +
                                             motion_y[2] + motion_y[3], 2);
                    }
                    if (s->version <= 2) {
                        motion_x[0] = (motion_x[0] >> 1) | (motion_x[0] & 1);
                        motion_y[0] = (motion_y[0] >> 1) | (motion_y[0] & 1);
                    }
                    frag = mb_y * s->fragment_width[1] + mb_x;
                    s->motion_val[1][frag][0] = motion_x[0];
                    s->motion_val[1][frag][1] = motion_y[0];
                } else if (s->chroma_x_shift) {
                    if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
                        motion_x[0] = RSHIFT(motion_x[0] + motion_x[1], 1);
                        motion_y[0] = RSHIFT(motion_y[0] + motion_y[1], 1);
                        motion_x[1] = RSHIFT(motion_x[2] + motion_x[3], 1);
                        motion_y[1] = RSHIFT(motion_y[2] + motion_y[3], 1);
                    } else {
                        motion_x[1] = motion_x[0];
                        motion_y[1] = motion_y[0];
                    }
                    if (s->version <= 2) {
                        motion_x[0] = (motion_x[0] >> 1) | (motion_x[0] & 1);
                        motion_x[1] = (motion_x[1] >> 1) | (motion_x[1] & 1);
                    }
                    frag = 2 * mb_y * s->fragment_width[1] + mb_x;
                    for (int k = 0; k < 2; k++) {
                        s->motion_val[1][frag][0] = motion_x[k];
                        s->motion_val[1][frag][1] = motion_y[k];
                        frag += s->fragment_width[1];
                    }
                } else {
                    for (int k = 0; k < 4; k++) {
                        frag = BLOCK_Y * s->fragment_width[1] + BLOCK_X;
                        if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
                            s->motion_val[1][frag][0] = motion_x[k];
                            s->motion_val[1][frag][1] = motion_y[k];
                        } else {
                            s->motion_val[1][frag][0] = motion_x[0];
                            s->motion_val[1][frag][1] = motion_y[0];
                        }
                    }
                }
            }
        }
    }

    return 0;
}

static int unpack_block_qpis(Vp3DecodeContext *s, GetBitContext *gb)
{
    int num_blocks = s->total_num_coded_frags;

    for (int qpi = 0; qpi < s->nqps - 1 && num_blocks > 0; qpi++) {
        int i = 0, blocks_decoded = 0, num_blocks_at_qpi = 0;
        int bit, run_length;

        bit        = get_bits1(gb) ^ 1;
        run_length = 0;

        do {
            if (run_length == MAXIMUM_LONG_BIT_RUN)
                bit = get_bits1(gb);
            else
                bit ^= 1;

            run_length = get_vlc2(gb, superblock_run_length_vlc,
                                  SUPERBLOCK_VLC_BITS, 2);
            if (run_length == 34)
                run_length += get_bits(gb, 12);
            blocks_decoded += run_length;

            if (!bit)
                num_blocks_at_qpi += run_length;

            for (int j = 0; j < run_length; i++) {
                if (i >= s->total_num_coded_frags)
                    return -1;

                if (s->all_fragments[s->coded_fragment_list[0][i]].qpi == qpi) {
                    s->all_fragments[s->coded_fragment_list[0][i]].qpi += bit;
                    j++;
                }
            }
        } while (blocks_decoded < num_blocks && get_bits_left(gb) > 0);

        num_blocks -= num_blocks_at_qpi;
    }

    return 0;
}

static inline int get_eob_run(GetBitContext *gb, int token)
{
    int v = eob_run_table[token].base;
    if (eob_run_table[token].bits)
        v += get_bits(gb, eob_run_table[token].bits);
    return v;
}

static inline int get_coeff(GetBitContext *gb, int token, int16_t *coeff)
{
    int bits_to_get, zero_run;

    bits_to_get = coeff_get_bits[token];
    if (bits_to_get)
        bits_to_get = get_bits(gb, bits_to_get);
    *coeff = coeff_tables[token][bits_to_get];

    zero_run = zero_run_base[token];
    if (zero_run_get_bits[token])
        zero_run += get_bits(gb, zero_run_get_bits[token]);

    return zero_run;
}

/*
 * This function is called by unpack_dct_coeffs() to extract the VLCs from
 * the bitstream. The VLCs encode tokens which are used to unpack DCT
 * data. This function unpacks all the VLCs for either the Y plane or both
 * C planes, and is called for DC coefficients or different AC coefficient
 * levels (since different coefficient types require different VLC tables.
 *
 * This function returns a residual eob run. E.g, if a particular token gave
 * instructions to EOB the next 5 fragments and there were only 2 fragments
 * left in the current fragment range, 3 would be returned so that it could
 * be passed into the next call to this same function.
 */
static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
                       const VLCElem *vlc_table, int coeff_index,
                       int plane,
                       int eob_run)
{
    int j = 0;
    int token;
    int zero_run  = 0;
    int16_t coeff = 0;
    int blocks_ended;
    int coeff_i = 0;
    int num_coeffs      = s->num_coded_frags[plane][coeff_index];
    int16_t *dct_tokens = s->dct_tokens[plane][coeff_index];

    /* local references to structure members to avoid repeated dereferences */
    const int *coded_fragment_list = s->coded_fragment_list[plane];
    Vp3Fragment *all_fragments = s->all_fragments;

    if (num_coeffs < 0) {
        av_log(s->avctx, AV_LOG_ERROR,
               "Invalid number of coefficients at level %d\n", coeff_index);
        return AVERROR_INVALIDDATA;
    }

    if (eob_run > num_coeffs) {
        coeff_i      =
        blocks_ended = num_coeffs;
        eob_run     -= num_coeffs;
    } else {
        coeff_i      =
        blocks_ended = eob_run;
        eob_run      = 0;
    }

    // insert fake EOB token to cover the split between planes or zzi
    if (blocks_ended)
        dct_tokens[j++] = blocks_ended << 2;

    while (coeff_i < num_coeffs && get_bits_left(gb) > 0) {
        /* decode a VLC into a token */
        token = get_vlc2(gb, vlc_table, 11, 3);
        /* use the token to get a zero run, a coefficient, and an eob run */
        if ((unsigned) token <= 6U) {
            eob_run = get_eob_run(gb, token);
            if (!eob_run)
                eob_run = INT_MAX;

            // record only the number of blocks ended in this plane,
            // any spill will be recorded in the next plane.
            if (eob_run > num_coeffs - coeff_i) {
                dct_tokens[j++] = TOKEN_EOB(num_coeffs - coeff_i);
                blocks_ended   += num_coeffs - coeff_i;
                eob_run        -= num_coeffs - coeff_i;
                coeff_i         = num_coeffs;
            } else {
                dct_tokens[j++] = TOKEN_EOB(eob_run);
                blocks_ended   += eob_run;
                coeff_i        += eob_run;
                eob_run         = 0;
            }
        } else if (token >= 0) {
            zero_run = get_coeff(gb, token, &coeff);

            if (zero_run) {
                dct_tokens[j++] = TOKEN_ZERO_RUN(coeff, zero_run);
            } else {
                // Save DC into the fragment structure. DC prediction is
                // done in raster order, so the actual DC can't be in with
                // other tokens. We still need the token in dct_tokens[]
                // however, or else the structure collapses on itself.
                if (!coeff_index)
                    all_fragments[coded_fragment_list[coeff_i]].dc = coeff;

                dct_tokens[j++] = TOKEN_COEFF(coeff);
            }

            if (coeff_index + zero_run > 64) {
                av_log(s->avctx, AV_LOG_DEBUG,
                       "Invalid zero run of %d with %d coeffs left\n",
                       zero_run, 64 - coeff_index);
                zero_run = 64 - coeff_index;
            }

            // zero runs code multiple coefficients,
            // so don't try to decode coeffs for those higher levels
            for (int i = coeff_index + 1; i <= coeff_index + zero_run; i++)
                s->num_coded_frags[plane][i]--;
            coeff_i++;
        } else {
            av_log(s->avctx, AV_LOG_ERROR, "Invalid token %d\n", token);
            return -1;
        }
    }

    if (blocks_ended > s->num_coded_frags[plane][coeff_index])
        av_log(s->avctx, AV_LOG_ERROR, "More blocks ended than coded!\n");

    // decrement the number of blocks that have higher coefficients for each
    // EOB run at this level
    if (blocks_ended)
        for (int i = coeff_index + 1; i < 64; i++)
            s->num_coded_frags[plane][i] -= blocks_ended;

    // setup the next buffer
    if (plane < 2)
        s->dct_tokens[plane + 1][coeff_index] = dct_tokens + j;
    else if (coeff_index < 63)
        s->dct_tokens[0][coeff_index + 1] = dct_tokens + j;

    return eob_run;
}

static void reverse_dc_prediction(Vp3DecodeContext *s,
                                  int first_fragment,
                                  int fragment_width,
                                  int fragment_height);
/*
 * This function unpacks all of the DCT coefficient data from the
 * bitstream.
 */
static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
{
    const VLCElem *const *coeff_vlc = s->coeff_vlc->vlc_tabs;
    int dc_y_table;
    int dc_c_table;
    int ac_y_table;
    int ac_c_table;
    int residual_eob_run = 0;
    const VLCElem *y_tables[64], *c_tables[64];

    s->dct_tokens[0][0] = s->dct_tokens_base;

    if (get_bits_left(gb) < 16)
        return AVERROR_INVALIDDATA;

    /* fetch the DC table indexes */
    dc_y_table = get_bits(gb, 4);
    dc_c_table = get_bits(gb, 4);

    /* unpack the Y plane DC coefficients */
    residual_eob_run = unpack_vlcs(s, gb, coeff_vlc[dc_y_table], 0,
                                   0, residual_eob_run);
    if (residual_eob_run < 0)
        return residual_eob_run;
    if (get_bits_left(gb) < 8)
        return AVERROR_INVALIDDATA;

    /* reverse prediction of the Y-plane DC coefficients */
    reverse_dc_prediction(s, 0, s->fragment_width[0], s->fragment_height[0]);

    /* unpack the C plane DC coefficients */
    residual_eob_run = unpack_vlcs(s, gb, coeff_vlc[dc_c_table], 0,
                                   1, residual_eob_run);
    if (residual_eob_run < 0)
        return residual_eob_run;
    residual_eob_run = unpack_vlcs(s, gb, coeff_vlc[dc_c_table], 0,
                                   2, residual_eob_run);
    if (residual_eob_run < 0)
        return residual_eob_run;

    /* reverse prediction of the C-plane DC coefficients */
    if (!(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
        reverse_dc_prediction(s, s->fragment_start[1],
                              s->fragment_width[1], s->fragment_height[1]);
        reverse_dc_prediction(s, s->fragment_start[2],
                              s->fragment_width[1], s->fragment_height[1]);
    }

    if (get_bits_left(gb) < 8)
        return AVERROR_INVALIDDATA;
    /* fetch the AC table indexes */
    ac_y_table = get_bits(gb, 4);
    ac_c_table = get_bits(gb, 4);

    /* build tables of AC VLC tables */
    for (int i = 1; i <= 5; i++) {
        /* AC VLC table group 1 */
        y_tables[i] = coeff_vlc[ac_y_table + 16];
        c_tables[i] = coeff_vlc[ac_c_table + 16];
    }
    for (int i = 6; i <= 14; i++) {
        /* AC VLC table group 2 */
        y_tables[i] = coeff_vlc[ac_y_table + 32];
        c_tables[i] = coeff_vlc[ac_c_table + 32];
    }
    for (int i = 15; i <= 27; i++) {
        /* AC VLC table group 3 */
        y_tables[i] = coeff_vlc[ac_y_table + 48];
        c_tables[i] = coeff_vlc[ac_c_table + 48];
    }
    for (int i = 28; i <= 63; i++) {
        /* AC VLC table group 4 */
        y_tables[i] = coeff_vlc[ac_y_table + 64];
        c_tables[i] = coeff_vlc[ac_c_table + 64];
    }

    /* decode all AC coefficients */
    for (int i = 1; i <= 63; i++) {
        residual_eob_run = unpack_vlcs(s, gb, y_tables[i], i,
                                       0, residual_eob_run);
        if (residual_eob_run < 0)
            return residual_eob_run;

        residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i,
                                       1, residual_eob_run);
        if (residual_eob_run < 0)
            return residual_eob_run;
        residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i,
                                       2, residual_eob_run);
        if (residual_eob_run < 0)
            return residual_eob_run;
    }

    return 0;
}

#if CONFIG_VP4_DECODER
/**
 * eob_tracker[] is instead of TOKEN_EOB(value)
 * a dummy TOKEN_EOB(0) value is used to make vp3_dequant work
 *
 * @return < 0 on error
 */
static int vp4_unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
                           const VLCElem *const vlc_tables[64],
                       int plane, int eob_tracker[64], int fragment)
{
    int token;
    int zero_run  = 0;
    int16_t coeff = 0;
    int coeff_i = 0;
    int eob_run;

    while (!eob_tracker[coeff_i]) {
        if (get_bits_left(gb) < 1)
            return AVERROR_INVALIDDATA;

        token = get_vlc2(gb, vlc_tables[coeff_i], 11, 3);

        /* use the token to get a zero run, a coefficient, and an eob run */
        if ((unsigned) token <= 6U) {
            eob_run = get_eob_run(gb, token);
            *s->dct_tokens[plane][coeff_i]++ = TOKEN_EOB(0);
            eob_tracker[coeff_i] = eob_run - 1;
            return 0;
        } else if (token >= 0) {
            zero_run = get_coeff(gb, token, &coeff);

            if (zero_run) {
                if (coeff_i + zero_run > 64) {
                    av_log(s->avctx, AV_LOG_DEBUG,
                        "Invalid zero run of %d with %d coeffs left\n",
                        zero_run, 64 - coeff_i);
                    zero_run = 64 - coeff_i;
                }
                *s->dct_tokens[plane][coeff_i]++ = TOKEN_ZERO_RUN(coeff, zero_run);
                coeff_i += zero_run;
            } else {
                if (!coeff_i)
                    s->all_fragments[fragment].dc = coeff;

                *s->dct_tokens[plane][coeff_i]++ = TOKEN_COEFF(coeff);
            }
            coeff_i++;
            if (coeff_i >= 64) /* > 64 occurs when there is a zero_run overflow */
                return 0; /* stop */
        } else {
            av_log(s->avctx, AV_LOG_ERROR, "Invalid token %d\n", token);
            return -1;
        }
    }
    *s->dct_tokens[plane][coeff_i]++ = TOKEN_EOB(0);
    eob_tracker[coeff_i]--;
    return 0;
}

static void vp4_dc_predictor_reset(VP4Predictor *p)
{
    p->dc = 0;
    p->type = VP4_DC_UNDEFINED;
}

static void vp4_dc_pred_before(const Vp3DecodeContext *s, VP4Predictor dc_pred[6][6], int sb_x)
{
    for (int i = 0; i < 4; i++)
        dc_pred[0][i + 1] = s->dc_pred_row[sb_x * 4 + i];

    for (int j = 1; j < 5; j++)
        for (int i = 0; i < 4; i++)
            vp4_dc_predictor_reset(&dc_pred[j][i + 1]);
}

static void vp4_dc_pred_after(Vp3DecodeContext *s, VP4Predictor dc_pred[6][6], int sb_x)
{
    for (int i = 0; i < 4; i++)
        s->dc_pred_row[sb_x * 4 + i] = dc_pred[4][i + 1];

    for (int i = 1; i < 5; i++)
        dc_pred[i][0] = dc_pred[i][4];
}

/* note: dc_pred points to the current block */
static int vp4_dc_pred(const Vp3DecodeContext *s, const VP4Predictor * dc_pred, const int * last_dc, int type, int plane)
{
    int count = 0;
    int dc = 0;

    if (dc_pred[-6].type == type) {
        dc += dc_pred[-6].dc;
        count++;
    }

    if (dc_pred[6].type == type) {
        dc += dc_pred[6].dc;
        count++;
    }

    if (count != 2 && dc_pred[-1].type == type) {
        dc += dc_pred[-1].dc;
        count++;
    }

    if (count != 2 && dc_pred[1].type == type) {
        dc += dc_pred[1].dc;
        count++;
    }

    /* using division instead of shift to correctly handle negative values */
    return count == 2 ? dc / 2 : last_dc[type];
}

static void vp4_set_tokens_base(Vp3DecodeContext *s)
{
    int16_t *base = s->dct_tokens_base;
    for (int plane = 0; plane < 3; plane++) {
        for (int i = 0; i < 64; i++) {
            s->dct_tokens[plane][i] = base;
            base += s->fragment_width[!!plane] * s->fragment_height[!!plane];
        }
    }
}

static int vp4_unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
{
    const VLCElem *const *coeff_vlc = s->coeff_vlc->vlc_tabs;
    int dc_y_table;
    int dc_c_table;
    int ac_y_table;
    int ac_c_table;
    const VLCElem *tables[2][64];
    int eob_tracker[64];
    VP4Predictor dc_pred[6][6];
    int last_dc[NB_VP4_DC_TYPES];

    if (get_bits_left(gb) < 16)
        return AVERROR_INVALIDDATA;

    /* fetch the DC table indexes */
    dc_y_table = get_bits(gb, 4);
    dc_c_table = get_bits(gb, 4);

    ac_y_table = get_bits(gb, 4);
    ac_c_table = get_bits(gb, 4);

    /* build tables of DC/AC VLC tables */

    /* DC table group */
    tables[0][0] = coeff_vlc[dc_y_table];
    tables[1][0] = coeff_vlc[dc_c_table];
    for (int i = 1; i <= 5; i++) {
        /* AC VLC table group 1 */
        tables[0][i] = coeff_vlc[ac_y_table + 16];
        tables[1][i] = coeff_vlc[ac_c_table + 16];
    }
    for (int i = 6; i <= 14; i++) {
        /* AC VLC table group 2 */
        tables[0][i] = coeff_vlc[ac_y_table + 32];
        tables[1][i] = coeff_vlc[ac_c_table + 32];
    }
    for (int i = 15; i <= 27; i++) {
        /* AC VLC table group 3 */
        tables[0][i] = coeff_vlc[ac_y_table + 48];
        tables[1][i] = coeff_vlc[ac_c_table + 48];
    }
    for (int i = 28; i <= 63; i++) {
        /* AC VLC table group 4 */
        tables[0][i] = coeff_vlc[ac_y_table + 64];
        tables[1][i] = coeff_vlc[ac_c_table + 64];
    }

    vp4_set_tokens_base(s);

    memset(last_dc, 0, sizeof(last_dc));

    for (int plane = 0; plane < ((s->avctx->flags & AV_CODEC_FLAG_GRAY) ? 1 : 3); plane++) {
        memset(eob_tracker, 0, sizeof(eob_tracker));

        /* initialise dc prediction */
        for (int i = 0; i < s->fragment_width[!!plane]; i++)
            vp4_dc_predictor_reset(&s->dc_pred_row[i]);

        for (int j = 0; j < 6; j++)
            for (int i = 0; i < 6; i++)
                vp4_dc_predictor_reset(&dc_pred[j][i]);

        for (int sb_y = 0; sb_y * 4 < s->fragment_height[!!plane]; sb_y++) {
            for (int sb_x = 0; sb_x *4 < s->fragment_width[!!plane]; sb_x++) {
                vp4_dc_pred_before(s, dc_pred, sb_x);
                for (int j = 0; j < 16; j++) {
                        int hx = hilbert_offset[j][0];
                        int hy = hilbert_offset[j][1];
                        int x  = 4 * sb_x + hx;
                        int y  = 4 * sb_y + hy;
                        VP4Predictor *this_dc_pred = &dc_pred[hy + 1][hx + 1];
                        int fragment, dc_block_type;

                        if (x >= s->fragment_width[!!plane] || y >= s->fragment_height[!!plane])
                            continue;

                        fragment = s->fragment_start[plane] + y * s->fragment_width[!!plane] + x;

                        if (s->all_fragments[fragment].coding_method == MODE_COPY)
                            continue;

                        if (vp4_unpack_vlcs(s, gb, tables[!!plane], plane, eob_tracker, fragment) < 0)
                            return -1;

                        dc_block_type = vp4_pred_block_type_map[s->all_fragments[fragment].coding_method];

                        s->all_fragments[fragment].dc +=
                            vp4_dc_pred(s, this_dc_pred, last_dc, dc_block_type, plane);

                        this_dc_pred->type = dc_block_type,
                        this_dc_pred->dc   = last_dc[dc_block_type] = s->all_fragments[fragment].dc;
                }
                vp4_dc_pred_after(s, dc_pred, sb_x);
            }
        }
    }

    vp4_set_tokens_base(s);

    return 0;
}
#endif

/*
 * This function reverses the DC prediction for each coded fragment in
 * the frame. Much of this function is adapted directly from the original
 * VP3 source code.
 */
#define COMPATIBLE_FRAME(x)                                                   \
    (compatible_frame[s->all_fragments[x].coding_method] == current_frame_type)
#define DC_COEFF(u) s->all_fragments[u].dc

static void reverse_dc_prediction(Vp3DecodeContext *s,
                                  int first_fragment,
                                  int fragment_width,
                                  int fragment_height)
{
#define PUL 8
#define PU 4
#define PUR 2
#define PL 1

    int i = first_fragment;

    int predicted_dc;

    /* DC values for the left, up-left, up, and up-right fragments */
    int vl, vul, vu, vur;

    /* indexes for the left, up-left, up, and up-right fragments */
    int l, ul, u, ur;

    /*
     * The 6 fields mean:
     *   0: up-left multiplier
     *   1: up multiplier
     *   2: up-right multiplier
     *   3: left multiplier
     */
    static const int predictor_transform[16][4] = {
        {    0,   0,   0,   0 },
        {    0,   0,   0, 128 }, // PL
        {    0,   0, 128,   0 }, // PUR
        {    0,   0,  53,  75 }, // PUR|PL
        {    0, 128,   0,   0 }, // PU
        {    0,  64,   0,  64 }, // PU |PL
        {    0, 128,   0,   0 }, // PU |PUR
        {    0,   0,  53,  75 }, // PU |PUR|PL
        {  128,   0,   0,   0 }, // PUL
        {    0,   0,   0, 128 }, // PUL|PL
        {   64,   0,  64,   0 }, // PUL|PUR
        {    0,   0,  53,  75 }, // PUL|PUR|PL
        {    0, 128,   0,   0 }, // PUL|PU
        { -104, 116,   0, 116 }, // PUL|PU |PL
        {   24,  80,  24,   0 }, // PUL|PU |PUR
        { -104, 116,   0, 116 }  // PUL|PU |PUR|PL
    };

    /* This table shows which types of blocks can use other blocks for
     * prediction. For example, INTRA is the only mode in this table to
     * have a frame number of 0. That means INTRA blocks can only predict
     * from other INTRA blocks. There are 2 golden frame coding types;
     * blocks encoding in these modes can only predict from other blocks
     * that were encoded with these 1 of these 2 modes. */
    static const unsigned char compatible_frame[9] = {
        1,    /* MODE_INTER_NO_MV */
        0,    /* MODE_INTRA */
        1,    /* MODE_INTER_PLUS_MV */
        1,    /* MODE_INTER_LAST_MV */
        1,    /* MODE_INTER_PRIOR_MV */
        2,    /* MODE_USING_GOLDEN */
        2,    /* MODE_GOLDEN_MV */
        1,    /* MODE_INTER_FOUR_MV */
        3     /* MODE_COPY */
    };
    int current_frame_type;

    /* there is a last DC predictor for each of the 3 frame types */
    short last_dc[3];

    int transform = 0;

    vul =
    vu  =
    vur =
    vl  = 0;
    last_dc[0] =
    last_dc[1] =
    last_dc[2] = 0;

    /* for each fragment row... */
    for (int y = 0; y < fragment_height; y++) {
        /* for each fragment in a row... */
        for (int x = 0; x < fragment_width; x++, i++) {

            /* reverse prediction if this block was coded */
            if (s->all_fragments[i].coding_method != MODE_COPY) {
                current_frame_type =
                    compatible_frame[s->all_fragments[i].coding_method];

                transform = 0;
                if (x) {
                    l  = i - 1;
                    vl = DC_COEFF(l);
                    if (COMPATIBLE_FRAME(l))
                        transform |= PL;
                }
                if (y) {
                    u  = i - fragment_width;
                    vu = DC_COEFF(u);
                    if (COMPATIBLE_FRAME(u))
                        transform |= PU;
                    if (x) {
                        ul  = i - fragment_width - 1;
                        vul = DC_COEFF(ul);
                        if (COMPATIBLE_FRAME(ul))
                            transform |= PUL;
                    }
                    if (x + 1 < fragment_width) {
                        ur  = i - fragment_width + 1;
                        vur = DC_COEFF(ur);
                        if (COMPATIBLE_FRAME(ur))
                            transform |= PUR;
                    }
                }

                if (transform == 0) {
                    /* if there were no fragments to predict from, use last
                     * DC saved */
                    predicted_dc = last_dc[current_frame_type];
                } else {
                    /* apply the appropriate predictor transform */
                    predicted_dc =
                        (predictor_transform[transform][0] * vul) +
                        (predictor_transform[transform][1] * vu) +
                        (predictor_transform[transform][2] * vur) +
                        (predictor_transform[transform][3] * vl);

                    predicted_dc /= 128;

                    /* check for outranging on the [ul u l] and
                     * [ul u ur l] predictors */
                    if ((transform == 15) || (transform == 13)) {
                        if (FFABS(predicted_dc - vu) > 128)
                            predicted_dc = vu;
                        else if (FFABS(predicted_dc - vl) > 128)
                            predicted_dc = vl;
                        else if (FFABS(predicted_dc - vul) > 128)
                            predicted_dc = vul;
                    }
                }

                /* at long last, apply the predictor */
                DC_COEFF(i) += predicted_dc;
                /* save the DC */
                last_dc[current_frame_type] = DC_COEFF(i);
            }
        }
    }
}

static void apply_loop_filter(Vp3DecodeContext *s, int plane,
                              int ystart, int yend)
{
    int *bounding_values = s->bounding_values_array + 127;

    int width           = s->fragment_width[!!plane];
    int height          = s->fragment_height[!!plane];
    int fragment        = s->fragment_start[plane] + ystart * width;
    ptrdiff_t stride    = s->current_frame.f->linesize[plane];
    uint8_t *plane_data = s->current_frame.f->data[plane];
    if (!s->flipped_image)
        stride = -stride;
    plane_data += s->data_offset[plane] + 8 * ystart * stride;

    for (int y = ystart; y < yend; y++) {
        for (int x = 0; x < width; x++) {
            /* This code basically just deblocks on the edges of coded blocks.
             * However, it has to be much more complicated because of the
             * brain damaged deblock ordering used in VP3/Theora. Order matters
             * because some pixels get filtered twice. */
            if (s->all_fragments[fragment].coding_method != MODE_COPY) {
                /* do not perform left edge filter for left columns frags */
                if (x > 0) {
                    s->vp3dsp.h_loop_filter(
                        plane_data + 8 * x,
                        stride, bounding_values);
                }

                /* do not perform top edge filter for top row fragments */
                if (y > 0) {
                    s->vp3dsp.v_loop_filter(
                        plane_data + 8 * x,
                        stride, bounding_values);
                }

                /* do not perform right edge filter for right column
                 * fragments or if right fragment neighbor is also coded
                 * in this frame (it will be filtered in next iteration) */
                if ((x < width - 1) &&
                    (s->all_fragments[fragment + 1].coding_method == MODE_COPY)) {
                    s->vp3dsp.h_loop_filter(
                        plane_data + 8 * x + 8,
                        stride, bounding_values);
                }

                /* do not perform bottom edge filter for bottom row
                 * fragments or if bottom fragment neighbor is also coded
                 * in this frame (it will be filtered in the next row) */
                if ((y < height - 1) &&
                    (s->all_fragments[fragment + width].coding_method == MODE_COPY)) {
                    s->vp3dsp.v_loop_filter(
                        plane_data + 8 * x + 8 * stride,
                        stride, bounding_values);
                }
            }

            fragment++;
        }
        plane_data += 8 * stride;
    }
}

/**
 * Pull DCT tokens from the 64 levels to decode and dequant the coefficients
 * for the next block in coding order
 */
static inline int vp3_dequant(Vp3DecodeContext *s, const Vp3Fragment *frag,
                              int plane, int inter, int16_t block[64])
{
    const int16_t *dequantizer = s->qmat[frag->qpi][inter][plane];
    const uint8_t *perm = s->idct_scantable;
    int i = 0;

    do {
        int token = *s->dct_tokens[plane][i];
        switch (token & 3) {
        case 0: // EOB
            if (--token < 4) // 0-3 are token types so the EOB run must now be 0
                s->dct_tokens[plane][i]++;
            else
                *s->dct_tokens[plane][i] = token & ~3;
            goto end;
        case 1: // zero run
            s->dct_tokens[plane][i]++;
            i += (token >> 2) & 0x7f;
            if (i > 63) {
                av_log(s->avctx, AV_LOG_ERROR, "Coefficient index overflow\n");
                return i;
            }
            block[perm[i]] = (token >> 9) * dequantizer[perm[i]];
            i++;
            break;
        case 2: // coeff
            block[perm[i]] = (token >> 2) * dequantizer[perm[i]];
            s->dct_tokens[plane][i++]++;
            break;
        default: // shouldn't happen
            return i;
        }
    } while (i < 64);
    // return value is expected to be a valid level
    i--;
end:
    // the actual DC+prediction is in the fragment structure
    block[0] = frag->dc * s->qmat[0][inter][plane][0];
    return i;
}

/**
 * called when all pixels up to row y are complete
 */
static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
{
    int h, cy;
    int offset[AV_NUM_DATA_POINTERS];

    if (HAVE_THREADS && s->avctx->active_thread_type & FF_THREAD_FRAME) {
        int y_flipped = s->flipped_image ? s->height - y : y;

        /* At the end of the frame, report INT_MAX instead of the height of
         * the frame. This makes the other threads' ff_thread_await_progress()
         * calls cheaper, because they don't have to clip their values. */
        ff_progress_frame_report(&s->current_frame,
                                 y_flipped == s->height ? INT_MAX
                                                        : y_flipped - 1);
    }

    if (!s->avctx->draw_horiz_band)
        return;

    h = y - s->last_slice_end;
    s->last_slice_end = y;
    y -= h;

    if (!s->flipped_image)
        y = s->height - y - h;

    cy        = y >> s->chroma_y_shift;
    offset[0] = s->current_frame.f->linesize[0] * y;
    offset[1] = s->current_frame.f->linesize[1] * cy;
    offset[2] = s->current_frame.f->linesize[2] * cy;
    for (int i = 3; i < AV_NUM_DATA_POINTERS; i++)
        offset[i] = 0;

    emms_c();
    s->avctx->draw_horiz_band(s->avctx, s->current_frame.f, offset, y, 3, h);
}

/**
 * Wait for the reference frame of the current fragment.
 * The progress value is in luma pixel rows.
 */
static void await_reference_row(Vp3DecodeContext *s, const Vp3Fragment *fragment,
                                int motion_y, int y)
{
    const ProgressFrame *ref_frame;
    int ref_row;
    int border = motion_y & 1;

    if (fragment->coding_method == MODE_USING_GOLDEN ||
        fragment->coding_method == MODE_GOLDEN_MV)
        ref_frame = &s->golden_frame;
    else
        ref_frame = &s->last_frame;

    ref_row = y + (motion_y >> 1);
    ref_row = FFMAX(FFABS(ref_row), ref_row + 8 + border);

    ff_progress_frame_await(ref_frame, ref_row);
}

#if CONFIG_VP4_DECODER
/**
 * @return non-zero if temp (edge_emu_buffer) was populated
 */
static int vp4_mc_loop_filter(Vp3DecodeContext *s, int plane, int motion_x, int motion_y, int bx, int by,
                              const uint8_t *motion_source, ptrdiff_t stride,
                              int src_x, int src_y, uint8_t *temp)
{
    int motion_shift = plane ? 4 : 2;
    int subpel_mask = plane ? 3 : 1;
    int *bounding_values = s->bounding_values_array + 127;

    int x, y;
    int x2, y2;
    int x_subpel, y_subpel;
    int x_offset, y_offset;

    int block_width = plane ? 8 : 16;
    int plane_width  = s->width  >> (plane && s->chroma_x_shift);
    int plane_height = s->height >> (plane && s->chroma_y_shift);

#define loop_stride 12
    uint8_t loop[12 * loop_stride];

    /* using division instead of shift to correctly handle negative values */
    x = 8 * bx + motion_x / motion_shift;
    y = 8 * by + motion_y / motion_shift;

    x_subpel = motion_x & subpel_mask;
    y_subpel = motion_y & subpel_mask;

    if (x_subpel || y_subpel) {
        x--;
        y--;

        if (x_subpel)
            x = FFMIN(x, x + FFSIGN(motion_x));

        if (y_subpel)
            y = FFMIN(y, y + FFSIGN(motion_y));

        x2 = x + block_width;
        y2 = y + block_width;

        if (x2 < 0 || x2 >= plane_width || y2 < 0 || y2 >= plane_height)
            return 0;

        x_offset = (-(x + 2) & 7) + 2;
        y_offset = (-(y + 2) & 7) + 2;

        av_assert1(!(x_offset > 8 + x_subpel && y_offset > 8 + y_subpel));

        s->vdsp.emulated_edge_mc(loop, motion_source - stride - 1,
             loop_stride, stride,
             12, 12, src_x - 1, src_y - 1,
             plane_width,
             plane_height);

        if (x_offset <= 8 + x_subpel)
            ff_vp3dsp_h_loop_filter_12(loop + x_offset, loop_stride, bounding_values);

        if (y_offset <= 8 + y_subpel)
            ff_vp3dsp_v_loop_filter_12(loop + y_offset*loop_stride, loop_stride, bounding_values);

    } else {

        x_offset = -x & 7;
        y_offset = -y & 7;

        if (!x_offset && !y_offset)
            return 0;

        s->vdsp.emulated_edge_mc(loop, motion_source - stride - 1,
             loop_stride, stride,
             12, 12, src_x - 1, src_y - 1,
             plane_width,
             plane_height);

#define safe_loop_filter(name, ptr, stride, bounding_values) \
    if ((uintptr_t)(ptr) & 7) \
        s->vp3dsp.name##_unaligned(ptr, stride, bounding_values); \
    else \
        s->vp3dsp.name(ptr, stride, bounding_values);

        if (x_offset)
            safe_loop_filter(h_loop_filter, loop + loop_stride + x_offset + 1, loop_stride, bounding_values);

        if (y_offset)
            safe_loop_filter(v_loop_filter, loop + (y_offset + 1)*loop_stride + 1, loop_stride, bounding_values);
    }

    for (int i = 0; i < 9; i++)
        memcpy(temp + i*stride, loop + (i + 1) * loop_stride + 1, 9);

    return 1;
}
#endif

/*
 * Perform the final rendering for a particular slice of data.
 * The slice number ranges from 0..(c_superblock_height - 1).
 */
static void render_slice(Vp3DecodeContext *s, int slice)
{
    int16_t *block = s->block;
    int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef;
    /* When decoding keyframes, the earlier frames may not be available,
     * so we just use the current frame in this case instead;
     * it also avoid using undefined pointer arithmetic. Nothing is
     * ever read from these frames in case of a keyframe. */
    const AVFrame *last_frame   = s->last_frame.f   ?
                                      s->last_frame.f   : s->current_frame.f;
    const AVFrame *golden_frame = s->golden_frame.f ?
                                      s->golden_frame.f : s->current_frame.f;
    int motion_halfpel_index;
    int first_pixel;

    if (slice >= s->c_superblock_height)
        return;

    for (int plane = 0; plane < 3; plane++) {
        uint8_t *output_plane = s->current_frame.f->data[plane] +
                                s->data_offset[plane];
        const uint8_t *last_plane = last_frame->data[plane] +
                              s->data_offset[plane];
        const uint8_t *golden_plane = golden_frame->data[plane] +
                                s->data_offset[plane];
        ptrdiff_t stride = s->current_frame.f->linesize[plane];
        int plane_width  = s->width  >> (plane && s->chroma_x_shift);
        int plane_height = s->height >> (plane && s->chroma_y_shift);
        const int8_t (*motion_val)[2] = s->motion_val[!!plane];

        int sb_y = slice << (!plane && s->chroma_y_shift);
        int slice_height = sb_y + 1 + (!plane && s->chroma_y_shift);
        int slice_width  = plane ? s->c_superblock_width
                                 : s->y_superblock_width;

        int fragment_width  = s->fragment_width[!!plane];
        int fragment_height = s->fragment_height[!!plane];
        int fragment_start  = s->fragment_start[plane];

        int do_await = !plane && HAVE_THREADS &&
                       (s->avctx->active_thread_type & FF_THREAD_FRAME);

        if (!s->flipped_image)
            stride = -stride;
        if (CONFIG_GRAY && plane && (s->avctx->flags & AV_CODEC_FLAG_GRAY))
            continue;

        /* for each superblock row in the slice (both of them)... */
        for (; sb_y < slice_height; sb_y++) {
            /* for each superblock in a row... */
            for (int sb_x = 0; sb_x < slice_width; sb_x++) {
                /* for each block in a superblock... */
                for (int j = 0; j < 16; j++) {
                    int x        = 4 * sb_x + hilbert_offset[j][0];
                    int y        = 4 * sb_y + hilbert_offset[j][1];
                    int fragment = y * fragment_width + x;

                    int i = fragment_start + fragment;

                    // bounds check
                    if (x >= fragment_width || y >= fragment_height)
                        continue;

                    first_pixel = 8 * y * stride + 8 * x;

                    if (do_await &&
                        s->all_fragments[i].coding_method != MODE_INTRA)
                        await_reference_row(s, &s->all_fragments[i],
                                            motion_val[fragment][1],
                                            (16 * y) >> s->chroma_y_shift);

                    /* transform if this block was coded */
                    if (s->all_fragments[i].coding_method != MODE_COPY) {
                        const uint8_t *motion_source;
                        if ((s->all_fragments[i].coding_method == MODE_USING_GOLDEN) ||
                            (s->all_fragments[i].coding_method == MODE_GOLDEN_MV))
                            motion_source = golden_plane;
                        else
                            motion_source = last_plane;

                        motion_source       += first_pixel;
                        motion_halfpel_index = 0;

                        /* sort out the motion vector if this fragment is coded
                         * using a motion vector method */
                        if ((s->all_fragments[i].coding_method > MODE_INTRA) &&
                            (s->all_fragments[i].coding_method != MODE_USING_GOLDEN)) {
                            int src_x, src_y;
                            int standard_mc = 1;
                            motion_x = motion_val[fragment][0];
                            motion_y = motion_val[fragment][1];
#if CONFIG_VP4_DECODER
                            if (plane && s->version >= 2) {
                                motion_x = (motion_x >> 1) | (motion_x & 1);
                                motion_y = (motion_y >> 1) | (motion_y & 1);
                            }
#endif

                            src_x = (motion_x >> 1) + 8 * x;
                            src_y = (motion_y >> 1) + 8 * y;

                            motion_halfpel_index = motion_x & 0x01;
                            motion_source       += (motion_x >> 1);

                            motion_halfpel_index |= (motion_y & 0x01) << 1;
                            motion_source        += ((motion_y >> 1) * stride);

#if CONFIG_VP4_DECODER
                            if (s->version >= 2) {
                                uint8_t *temp = s->edge_emu_buffer;
                                if (stride < 0)
                                    temp -= 8 * stride;
                                if (vp4_mc_loop_filter(s, plane, motion_val[fragment][0], motion_val[fragment][1], x, y, motion_source, stride, src_x, src_y, temp)) {
                                    motion_source = temp;
                                    standard_mc = 0;
                                }
                            }
#endif

                            if (standard_mc && (
                                src_x < 0 || src_y < 0 ||
                                src_x + 9 >= plane_width ||
                                src_y + 9 >= plane_height)) {
                                uint8_t *temp = s->edge_emu_buffer;
                                if (stride < 0)
                                    temp -= 8 * stride;

                                s->vdsp.emulated_edge_mc(temp, motion_source,
                                                         stride, stride,
                                                         9, 9, src_x, src_y,
                                                         plane_width,
                                                         plane_height);
                                motion_source = temp;
                            }
                        }

                        /* first, take care of copying a block from either the
                         * previous or the golden frame */
                        if (s->all_fragments[i].coding_method != MODE_INTRA) {
                            /* Note, it is possible to implement all MC cases
                             * with put_no_rnd_pixels_l2 which would look more
                             * like the VP3 source but this would be slower as
                             * put_no_rnd_pixels_tab is better optimized */
                            if (motion_halfpel_index != 3) {
                                s->hdsp.put_no_rnd_pixels_tab[1][motion_halfpel_index](
                                    output_plane + first_pixel,
                                    motion_source, stride, 8);
                            } else {
                                /* d is 0 if motion_x and _y have the same sign,
                                 * else -1 */
                                int d = (motion_x ^ motion_y) >> 31;
                                s->vp3dsp.put_no_rnd_pixels_l2(output_plane + first_pixel,
                                                               motion_source - d,
                                                               motion_source + stride + 1 + d,
                                                               stride, 8);
                            }
                        }

                        /* invert DCT and place (or add) in final output */

                        if (s->all_fragments[i].coding_method == MODE_INTRA) {
                            vp3_dequant(s, s->all_fragments + i,
                                        plane, 0, block);
                            s->vp3dsp.idct_put(output_plane + first_pixel,
                                               stride,
                                               block);
                        } else {
                            if (vp3_dequant(s, s->all_fragments + i,
                                            plane, 1, block)) {
                                s->vp3dsp.idct_add(output_plane + first_pixel,
                                                   stride,
                                                   block);
                            } else {
                                s->vp3dsp.idct_dc_add(output_plane + first_pixel,
                                                      stride, block);
                            }
                        }
                    } else {
                        /* copy directly from the previous frame */
                        s->hdsp.put_pixels_tab[1][0](
                            output_plane + first_pixel,
                            last_plane + first_pixel,
                            stride, 8);
                    }
                }
            }

            // Filter up to the last row in the superblock row
            if (s->version < 2 && !s->skip_loop_filter)
                apply_loop_filter(s, plane, 4 * sb_y - !!sb_y,
                                  FFMIN(4 * sb_y + 3, fragment_height - 1));
        }
    }

    /* this looks like a good place for slice dispatch... */
    /* algorithm:
     *   if (slice == s->macroblock_height - 1)
     *     dispatch (both last slice & 2nd-to-last slice);
     *   else if (slice > 0)
     *     dispatch (slice - 1);
     */

    vp3_draw_horiz_band(s, FFMIN((32 << s->chroma_y_shift) * (slice + 1) - 16,
                                 s->height - 16));
}

static av_cold void init_tables_once(void)
{
    VLCInitState state = VLC_INIT_STATE(mode_code_vlc);

    VLC_INIT_STATIC_TABLE_FROM_LENGTHS(superblock_run_length_vlc,
                                       SUPERBLOCK_VLC_BITS, 34,
                                       superblock_run_length_vlc_lens, 1,
                                       NULL, 0, 0, 1, 0);

    VLC_INIT_STATIC_TABLE_FROM_LENGTHS(fragment_run_length_vlc, 5, 30,
                                       fragment_run_length_vlc_len, 1,
                                       NULL, 0, 0, 0, 0);

    VLC_INIT_STATIC_TABLE_FROM_LENGTHS(motion_vector_vlc, VP3_MV_VLC_BITS, 63,
                                       &motion_vector_vlc_table[0][1], 2,
                                       &motion_vector_vlc_table[0][0], 2, 1,
                                       -31, 0);

    ff_vlc_init_tables_from_lengths(&state, 4, 8,
                                    mode_code_vlc_len, 1,
                                    NULL, 0, 0, 0, 0);

#if CONFIG_VP4_DECODER
    for (int j = 0; j < 2; j++)
        for (int i = 0; i < 7; i++) {
            vp4_mv_vlc_table[j][i] =
                ff_vlc_init_tables_from_lengths(&state, VP4_MV_VLC_BITS, 63,
                                                &vp4_mv_vlc[j][i][0][1], 2,
                                                &vp4_mv_vlc[j][i][0][0], 2, 1,
                                                -31, 0);
        }

    /* version >= 2 */
    for (int i = 0; i < 2; i++) {
        block_pattern_vlc[i] =
            ff_vlc_init_tables(&state, 5, 14,
                               &vp4_block_pattern_vlc[i][0][1], 2, 1,
                               &vp4_block_pattern_vlc[i][0][0], 2, 1, 0);
    }
#endif
}

/// Allocate tables for per-frame data in Vp3DecodeContext
static av_cold int allocate_tables(AVCodecContext *avctx)
{
    Vp3DecodeContext *s = avctx->priv_data;
    int y_fragment_count, c_fragment_count;

    free_tables(avctx);

    y_fragment_count = s->fragment_width[0] * s->fragment_height[0];
    c_fragment_count = s->fragment_width[1] * s->fragment_height[1];

    /* superblock_coding is used by unpack_superblocks (VP3/Theora) and vp4_unpack_macroblocks (VP4) */
    s->superblock_coding = av_mallocz(FFMAX(s->superblock_count, s->yuv_macroblock_count));
    s->all_fragments     = av_calloc(s->fragment_count, sizeof(*s->all_fragments));

    s-> kf_coded_fragment_list = av_calloc(s->fragment_count, sizeof(int));
    s->nkf_coded_fragment_list = av_calloc(s->fragment_count, sizeof(int));
    memset(s-> num_kf_coded_fragment, -1, sizeof(s-> num_kf_coded_fragment));

    s->dct_tokens_base = av_calloc(s->fragment_count,
                                   64 * sizeof(*s->dct_tokens_base));
    s->motion_val[0] = av_calloc(y_fragment_count, sizeof(*s->motion_val[0]));
    s->motion_val[1] = av_calloc(c_fragment_count, sizeof(*s->motion_val[1]));

    /* work out the block mapping tables */
    s->superblock_fragments = av_calloc(s->superblock_count, 16 * sizeof(int));
    s->macroblock_coding    = av_mallocz(s->macroblock_count + 1);

    s->dc_pred_row = av_malloc_array(s->y_superblock_width * 4, sizeof(*s->dc_pred_row));

    if (!s->superblock_coding    || !s->all_fragments          ||
        !s->dct_tokens_base      || !s->kf_coded_fragment_list ||
        !s->nkf_coded_fragment_list ||
        !s->superblock_fragments || !s->macroblock_coding      ||
        !s->dc_pred_row ||
        !s->motion_val[0]        || !s->motion_val[1]) {
        return -1;
    }

    init_block_mapping(s);

    return 0;
}


static av_cold void free_vlc_tables(FFRefStructOpaque unused, void *obj)
{
    CoeffVLCs *vlcs = obj;

    for (int i = 0; i < FF_ARRAY_ELEMS(vlcs->vlcs); i++)
        ff_vlc_free(&vlcs->vlcs[i]);
}

static av_cold int vp3_decode_init(AVCodecContext *avctx)
{
    static AVOnce init_static_once = AV_ONCE_INIT;
    Vp3DecodeContext *s = avctx->priv_data;
    int ret;
    int c_width;
    int c_height;
    int y_fragment_count, c_fragment_count;

    if (avctx->codec_tag == MKTAG('V', 'P', '4', '0')) {
        s->version = 3;
#if !CONFIG_VP4_DECODER
        av_log(avctx, AV_LOG_ERROR, "This build does not support decoding VP4.\n");
        return AVERROR_DECODER_NOT_FOUND;
#endif
    } else if (avctx->codec_tag == MKTAG('V', 'P', '3', '0'))
        s->version = 0;
    else
        s->version = 1;

    s->avctx  = avctx;
    s->width  = FFALIGN(avctx->coded_width, 16);
    s->height = FFALIGN(avctx->coded_height, 16);
    if (s->width < 18)
        return AVERROR_PATCHWELCOME;
    if (avctx->codec_id != AV_CODEC_ID_THEORA)
        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
    avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
    ff_hpeldsp_init(&s->hdsp, avctx->flags | AV_CODEC_FLAG_BITEXACT);
    ff_videodsp_init(&s->vdsp, 8);
    ff_vp3dsp_init(&s->vp3dsp, avctx->flags);

    for (int i = 0; i < 64; i++) {
#define TRANSPOSE(x) (((x) >> 3) | (((x) & 7) << 3))
        s->idct_permutation[i] = TRANSPOSE(i);
        s->idct_scantable[i]   = TRANSPOSE(ff_zigzag_direct[i]);
#undef TRANSPOSE
    }

    /* initialize to an impossible value which will force a recalculation
     * in the first frame decode */
    for (int i = 0; i < 3; i++)
        s->qps[i] = -1;

    ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);
    if (ret)
        return ret;

    s->y_superblock_width  = (s->width  + 31) / 32;
    s->y_superblock_height = (s->height + 31) / 32;
    s->y_superblock_count  = s->y_superblock_width * s->y_superblock_height;

    /* work out the dimensions for the C planes */
    c_width                = s->width >> s->chroma_x_shift;
    c_height               = s->height >> s->chroma_y_shift;
    s->c_superblock_width  = (c_width  + 31) / 32;
    s->c_superblock_height = (c_height + 31) / 32;
    s->c_superblock_count  = s->c_superblock_width * s->c_superblock_height;

    s->superblock_count   = s->y_superblock_count + (s->c_superblock_count * 2);
    s->u_superblock_start = s->y_superblock_count;
    s->v_superblock_start = s->u_superblock_start + s->c_superblock_count;

    s->macroblock_width  = (s->width  + 15) / 16;
    s->macroblock_height = (s->height + 15) / 16;
    s->macroblock_count  = s->macroblock_width * s->macroblock_height;
    s->c_macroblock_width  = (c_width  + 15) / 16;
    s->c_macroblock_height = (c_height + 15) / 16;
    s->c_macroblock_count  = s->c_macroblock_width * s->c_macroblock_height;
    s->yuv_macroblock_count = s->macroblock_count + 2 * s->c_macroblock_count;

    s->fragment_width[0]  = s->width / FRAGMENT_PIXELS;
    s->fragment_height[0] = s->height / FRAGMENT_PIXELS;
    s->fragment_width[1]  = s->fragment_width[0] >> s->chroma_x_shift;
    s->fragment_height[1] = s->fragment_height[0] >> s->chroma_y_shift;

    /* fragment count covers all 8x8 blocks for all 3 planes */
    y_fragment_count     = s->fragment_width[0] * s->fragment_height[0];
    c_fragment_count     = s->fragment_width[1] * s->fragment_height[1];
    s->fragment_count    = y_fragment_count + 2 * c_fragment_count;
    s->fragment_start[1] = y_fragment_count;
    s->fragment_start[2] = y_fragment_count + c_fragment_count;

    if (!s->theora_tables) {
        for (int i = 0; i < 64; i++) {
            s->coded_dc_scale_factor[0][i] = s->version < 2 ? vp31_dc_scale_factor[i] : vp4_y_dc_scale_factor[i];
            s->coded_dc_scale_factor[1][i] = s->version < 2 ? vp31_dc_scale_factor[i] : vp4_uv_dc_scale_factor[i];
            s->coded_ac_scale_factor[i] = s->version < 2 ? vp31_ac_scale_factor[i] : vp4_ac_scale_factor[i];
            s->base_matrix[0][i]        = s->version < 2 ? vp31_intra_y_dequant[i] : vp4_generic_dequant[i];
            s->base_matrix[1][i]        = s->version < 2 ? ff_mjpeg_std_chrominance_quant_tbl[i] : vp4_generic_dequant[i];
            s->base_matrix[2][i]        = s->version < 2 ? vp31_inter_dequant[i]   : vp4_generic_dequant[i];
            s->filter_limit_values[i]   = s->version < 2 ? vp31_filter_limit_values[i] : vp4_filter_limit_values[i];
        }

        for (int inter = 0; inter < 2; inter++) {
            for (int plane = 0; plane < 3; plane++) {
                s->qr_count[inter][plane]   = 1;
                s->qr_size[inter][plane][0] = 63;
                s->qr_base[inter][plane][0] =
                s->qr_base[inter][plane][1] = 2 * inter + (!!plane) * !inter;
            }
        }
    }

    if (!avctx->internal->is_copy) {
        CoeffVLCs *vlcs = ff_refstruct_alloc_ext(sizeof(*s->coeff_vlc), 0,
                                                 NULL, free_vlc_tables);
        if (!vlcs)
            return AVERROR(ENOMEM);

        s->coeff_vlc = vlcs;

        if (!s->theora_tables) {
            const uint8_t (*bias_tabs)[32][2];

            /* init VLC tables */
            bias_tabs = CONFIG_VP4_DECODER && s->version >= 2 ? vp4_bias : vp3_bias;
            for (int i = 0; i < FF_ARRAY_ELEMS(vlcs->vlcs); i++) {
                ret = ff_vlc_init_from_lengths(&vlcs->vlcs[i], 11, 32,
                                               &bias_tabs[i][0][1], 2,
                                               &bias_tabs[i][0][0], 2, 1,
                                               0, 0, avctx);
                if (ret < 0)
                    return ret;
                vlcs->vlc_tabs[i] = vlcs->vlcs[i].table;
            }
        } else {
            for (int i = 0; i < FF_ARRAY_ELEMS(vlcs->vlcs); i++) {
                const HuffTable *tab = &s->huffman_table[i];

                ret = ff_vlc_init_from_lengths(&vlcs->vlcs[i], 11, tab->nb_entries,
                                               &tab->entries[0].len, sizeof(*tab->entries),
                                               &tab->entries[0].sym, sizeof(*tab->entries), 1,
                                               0, 0, avctx);
                if (ret < 0)
                    return ret;
                vlcs->vlc_tabs[i] = vlcs->vlcs[i].table;
            }
        }
    }

    ff_thread_once(&init_static_once, init_tables_once);

    return allocate_tables(avctx);
}

/// Release and shuffle frames after decode finishes
static void update_frames(AVCodecContext *avctx)
{
    Vp3DecodeContext *s = avctx->priv_data;

    if (s->keyframe)
        ff_progress_frame_replace(&s->golden_frame, &s->current_frame);

    /* shuffle frames */
    ff_progress_frame_unref(&s->last_frame);
    FFSWAP(ProgressFrame, s->last_frame, s->current_frame);
}

#if HAVE_THREADS
static void ref_frames(Vp3DecodeContext *dst, const Vp3DecodeContext *src)
{
    ff_progress_frame_replace(&dst->current_frame, &src->current_frame);
    ff_progress_frame_replace(&dst->golden_frame,  &src->golden_frame);
    ff_progress_frame_replace(&dst->last_frame,    &src->last_frame);
}

static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
{
    Vp3DecodeContext *s = dst->priv_data;
    const Vp3DecodeContext *s1 = src->priv_data;
    int qps_changed = 0;

    ff_refstruct_replace(&s->coeff_vlc, s1->coeff_vlc);

    // copy previous frame data
    ref_frames(s, s1);
    if (!s1->current_frame.f ||
        s->width != s1->width || s->height != s1->height) {
        return -1;
    }

    if (s != s1) {
        s->keyframe = s1->keyframe;

        // copy qscale data if necessary
        for (int i = 0; i < 3; i++) {
            if (s->qps[i] != s1->qps[1]) {
                qps_changed = 1;
                memcpy(&s->qmat[i], &s1->qmat[i], sizeof(s->qmat[i]));
            }
        }

        if (s->qps[0] != s1->qps[0])
            memcpy(&s->bounding_values_array, &s1->bounding_values_array,
                   sizeof(s->bounding_values_array));

        if (qps_changed) {
            memcpy(s->qps,      s1->qps,      sizeof(s->qps));
            memcpy(s->last_qps, s1->last_qps, sizeof(s->last_qps));
            s->nqps = s1->nqps;
        }
    }

    update_frames(dst);
    return 0;
}
#endif

static int vp3_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                            int *got_frame, AVPacket *avpkt)
{
    const uint8_t *buf  = avpkt->data;
    int buf_size        = avpkt->size;
    Vp3DecodeContext *s = avctx->priv_data;
    GetBitContext gb;
    int ret;

    if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)
        return ret;

#if CONFIG_THEORA_DECODER
    if (s->theora && get_bits1(&gb)) {
        int type = get_bits(&gb, 7);
        skip_bits_long(&gb, 6*8); /* "theora" */

        if (s->avctx->active_thread_type&FF_THREAD_FRAME) {
            av_log(avctx, AV_LOG_ERROR, "midstream reconfiguration with multithreading is unsupported, try -threads 1\n");
            return AVERROR_PATCHWELCOME;
        }
        if (type == 0) {
            vp3_decode_end(avctx);
            ret = theora_decode_header(avctx, &gb);

            if (ret >= 0)
                ret = vp3_decode_init(avctx);
            if (ret < 0) {
                vp3_decode_end(avctx);
                return ret;
            }
            return buf_size;
        } else if (type == 2) {
            vp3_decode_end(avctx);
            ret = theora_decode_tables(avctx, &gb);
            if (ret >= 0)
                ret = vp3_decode_init(avctx);
            if (ret < 0) {
                vp3_decode_end(avctx);
                return ret;
            }
            return buf_size;
        }

        av_log(avctx, AV_LOG_ERROR,
               "Header packet passed to frame decoder, skipping\n");
        return -1;
    }
#endif

    s->keyframe = !get_bits1(&gb);
    if (!s->all_fragments) {
        av_log(avctx, AV_LOG_ERROR, "Data packet without prior valid headers\n");
        return -1;
    }
    if (!s->theora)
        skip_bits(&gb, 1);
    for (int i = 0; i < 3; i++)
        s->last_qps[i] = s->qps[i];

    s->nqps = 0;
    do {
        s->qps[s->nqps++] = get_bits(&gb, 6);
    } while (s->theora >= 0x030200 && s->nqps < 3 && get_bits1(&gb));
    for (int i = s->nqps; i < 3; i++)
        s->qps[i] = -1;

    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
        av_log(s->avctx, AV_LOG_INFO, " VP3 %sframe #%"PRId64": Q index = %d\n",
               s->keyframe ? "key" : "", avctx->frame_num + 1, s->qps[0]);

    s->skip_loop_filter = !s->filter_limit_values[s->qps[0]] ||
                          avctx->skip_loop_filter >= (s->keyframe ? AVDISCARD_ALL
                                                                  : AVDISCARD_NONKEY);

    if (s->qps[0] != s->last_qps[0])
        init_loop_filter(s);

    for (int i = 0; i < s->nqps; i++)
        // reinit all dequantizers if the first one changed, because
        // the DC of the first quantizer must be used for all matrices
        if (s->qps[i] != s->last_qps[i] || s->qps[0] != s->last_qps[0])
            init_dequantizer(s, i);

    if (avctx->skip_frame >= AVDISCARD_NONKEY && !s->keyframe)
        return buf_size;

    ff_progress_frame_unref(&s->current_frame);
    ret = ff_progress_frame_get_buffer(avctx, &s->current_frame,
                                       AV_GET_BUFFER_FLAG_REF);
    if (ret < 0) {
        // Don't goto error here, as one can't report progress on or
        // unref a non-existent frame.
        return ret;
    }
    s->current_frame.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I
                                                : AV_PICTURE_TYPE_P;
    if (s->keyframe)
        s->current_frame.f->flags |= AV_FRAME_FLAG_KEY;
    else
        s->current_frame.f->flags &= ~AV_FRAME_FLAG_KEY;

    if (!s->edge_emu_buffer) {
        s->edge_emu_buffer = av_malloc(9 * FFABS(s->current_frame.f->linesize[0]));
        if (!s->edge_emu_buffer) {
            ret = AVERROR(ENOMEM);
            goto error;
        }
    }

    if (s->keyframe) {
        if (!s->theora) {
            skip_bits(&gb, 4); /* width code */
            skip_bits(&gb, 4); /* height code */
            if (s->version) {
                int version = get_bits(&gb, 5);
#if !CONFIG_VP4_DECODER
                if (version >= 2) {
                    av_log(avctx, AV_LOG_ERROR, "This build does not support decoding VP4.\n");
                    return AVERROR_DECODER_NOT_FOUND;
                }
#endif
                s->version = version;
                if (avctx->frame_num == 0)
                    av_log(s->avctx, AV_LOG_DEBUG,
                           "VP version: %d\n", s->version);
            }
        }
        if (s->version || s->theora) {
            if (get_bits1(&gb))
                av_log(s->avctx, AV_LOG_ERROR,
                       "Warning, unsupported keyframe coding type?!\n");
            skip_bits(&gb, 2); /* reserved? */

#if CONFIG_VP4_DECODER
            if (s->version >= 2) {
                int mb_height, mb_width;
                int mb_width_mul, mb_width_div, mb_height_mul, mb_height_div;

                mb_height = get_bits(&gb, 8);
                mb_width  = get_bits(&gb, 8);
                if (mb_height != s->macroblock_height ||
                    mb_width != s->macroblock_width)
                    avpriv_request_sample(s->avctx, "macroblock dimension mismatch");

                mb_width_mul = get_bits(&gb, 5);
                mb_width_div = get_bits(&gb, 3);
                mb_height_mul = get_bits(&gb, 5);
                mb_height_div = get_bits(&gb, 3);
                if (mb_width_mul != 1 || mb_width_div != 1 || mb_height_mul != 1 || mb_height_div != 1)
                    avpriv_request_sample(s->avctx, "unexpected macroblock dimension multipler/divider");

                if (get_bits(&gb, 2))
                    avpriv_request_sample(s->avctx, "unknown bits");
            }
#endif
        }
    } else {
        if (!s->golden_frame.f) {
            av_log(s->avctx, AV_LOG_WARNING,
                   "vp3: first frame not a keyframe\n");

            if ((ret = ff_progress_frame_get_buffer(avctx, &s->golden_frame,
                                                    AV_GET_BUFFER_FLAG_REF)) < 0)
                goto error;
            s->golden_frame.f->pict_type = AV_PICTURE_TYPE_I;
            ff_progress_frame_replace(&s->last_frame, &s->golden_frame);
            ff_progress_frame_report(&s->golden_frame, INT_MAX);
        }
    }
    ff_thread_finish_setup(avctx);

    memset(s->all_fragments, 0, s->fragment_count * sizeof(Vp3Fragment));

    if (s->version < 2) {
        if ((ret = unpack_superblocks(s, &gb)) < 0) {
            av_log(s->avctx, AV_LOG_ERROR, "error in unpack_superblocks\n");
            goto error;
        }
#if CONFIG_VP4_DECODER
    } else {
        if ((ret = vp4_unpack_macroblocks(s, &gb)) < 0) {
            av_log(s->avctx, AV_LOG_ERROR, "error in vp4_unpack_macroblocks\n");
            goto error;
    }
#endif
    }
    if ((ret = unpack_modes(s, &gb)) < 0) {
        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_modes\n");
        goto error;
    }
    if (ret = unpack_vectors(s, &gb)) {
        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_vectors\n");
        goto error;
    }
    if ((ret = unpack_block_qpis(s, &gb)) < 0) {
        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_block_qpis\n");
        goto error;
    }

    if (s->version < 2) {
        if ((ret = unpack_dct_coeffs(s, &gb)) < 0) {
            av_log(s->avctx, AV_LOG_ERROR, "error in unpack_dct_coeffs\n");
            goto error;
        }
#if CONFIG_VP4_DECODER
    } else {
        if ((ret = vp4_unpack_dct_coeffs(s, &gb)) < 0) {
            av_log(s->avctx, AV_LOG_ERROR, "error in vp4_unpack_dct_coeffs\n");
            goto error;
        }
#endif
    }

    for (int i = 0; i < 3; i++) {
        int height = s->height >> (i && s->chroma_y_shift);
        if (s->flipped_image)
            s->data_offset[i] = 0;
        else
            s->data_offset[i] = (height - 1) * s->current_frame.f->linesize[i];
    }

    s->last_slice_end = 0;
    for (int i = 0; i < s->c_superblock_height; i++)
        render_slice(s, i);

    // filter the last row
    if (s->version < 2)
        for (int i = 0; i < 3; i++) {
            int row = (s->height >> (3 + (i && s->chroma_y_shift))) - 1;
            apply_loop_filter(s, i, row, row + 1);
        }
    vp3_draw_horiz_band(s, s->height);

    /* output frame, offset as needed */
    if ((ret = av_frame_ref(frame, s->current_frame.f)) < 0)
        return ret;

    frame->crop_left   = s->offset_x;
    frame->crop_right  = avctx->coded_width - avctx->width - s->offset_x;
    frame->crop_top    = s->offset_y;
    frame->crop_bottom = avctx->coded_height - avctx->height - s->offset_y;

    *got_frame = 1;

    if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME))
        update_frames(avctx);

    return buf_size;

error:
    ff_progress_frame_report(&s->current_frame, INT_MAX);

    if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME))
        av_frame_unref(s->current_frame.f);

    return ret;
}

static int read_huffman_tree(HuffTable *huff, GetBitContext *gb, int length,
                             AVCodecContext *avctx)
{
    if (get_bits1(gb)) {
        int token;
        if (huff->nb_entries >= 32) { /* overflow */
            av_log(avctx, AV_LOG_ERROR, "huffman tree overflow\n");
            return -1;
        }
        token = get_bits(gb, 5);
        ff_dlog(avctx, "code length %d, curr entry %d, token %d\n",
                length, huff->nb_entries, token);
        huff->entries[huff->nb_entries++] = (HuffEntry){ length, token };
    } else {
        /* The following bound follows from the fact that nb_entries <= 32. */
        if (length >= 31) { /* overflow */
            av_log(avctx, AV_LOG_ERROR, "huffman tree overflow\n");
            return -1;
        }
        length++;
        if (read_huffman_tree(huff, gb, length, avctx))
            return -1;
        if (read_huffman_tree(huff, gb, length, avctx))
            return -1;
    }
    return 0;
}

#if CONFIG_THEORA_DECODER
static const enum AVPixelFormat theora_pix_fmts[4] = {
    AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P
};

static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
{
    Vp3DecodeContext *s = avctx->priv_data;
    int visible_width, visible_height, colorspace;
    uint8_t offset_x = 0, offset_y = 0;
    int ret;
    AVRational fps, aspect;

    if (get_bits_left(gb) < 206)
        return AVERROR_INVALIDDATA;

    s->theora_header = 0;
    s->theora = get_bits(gb, 24);
    av_log(avctx, AV_LOG_DEBUG, "Theora bitstream version %X\n", s->theora);
    if (!s->theora) {
        s->theora = 1;
        avpriv_request_sample(s->avctx, "theora 0");
    }

    /* 3.2.0 aka alpha3 has the same frame orientation as original vp3
     * but previous versions have the image flipped relative to vp3 */
    if (s->theora < 0x030200) {
        s->flipped_image = 1;
        av_log(avctx, AV_LOG_DEBUG,
               "Old (<alpha3) Theora bitstream, flipped image\n");
    }

    visible_width  =
    s->width       = get_bits(gb, 16) << 4;
    visible_height =
    s->height      = get_bits(gb, 16) << 4;

    if (s->theora >= 0x030200) {
        visible_width  = get_bits(gb, 24);
        visible_height = get_bits(gb, 24);

        offset_x = get_bits(gb, 8); /* offset x */
        offset_y = get_bits(gb, 8); /* offset y, from bottom */
    }

    /* sanity check */
    if (av_image_check_size(visible_width, visible_height, 0, avctx) < 0 ||
        visible_width  + offset_x > s->width ||
        visible_height + offset_y > s->height ||
        visible_width < 18
    ) {
        av_log(avctx, AV_LOG_ERROR,
               "Invalid frame dimensions - w:%d h:%d x:%d y:%d (%dx%d).\n",
               visible_width, visible_height, offset_x, offset_y,
               s->width, s->height);
        return AVERROR_INVALIDDATA;
    }

    fps.num = get_bits_long(gb, 32);
    fps.den = get_bits_long(gb, 32);
    if (fps.num && fps.den) {
        if (fps.num < 0 || fps.den < 0) {
            av_log(avctx, AV_LOG_ERROR, "Invalid framerate\n");
            return AVERROR_INVALIDDATA;
        }
        av_reduce(&avctx->framerate.den, &avctx->framerate.num,
                  fps.den, fps.num, 1 << 30);
    }

    aspect.num = get_bits(gb, 24);
    aspect.den = get_bits(gb, 24);
    if (aspect.num && aspect.den) {
        av_reduce(&avctx->sample_aspect_ratio.num,
                  &avctx->sample_aspect_ratio.den,
                  aspect.num, aspect.den, 1 << 30);
        ff_set_sar(avctx, avctx->sample_aspect_ratio);
    }

    if (s->theora < 0x030200)
        skip_bits(gb, 5); /* keyframe frequency force */
    colorspace = get_bits(gb, 8);
    skip_bits(gb, 24); /* bitrate */

    skip_bits(gb, 6); /* quality hint */

    if (s->theora >= 0x030200) {
        skip_bits(gb, 5); /* keyframe frequency force */
        avctx->pix_fmt = theora_pix_fmts[get_bits(gb, 2)];
        if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
            av_log(avctx, AV_LOG_ERROR, "Invalid pixel format\n");
            return AVERROR_INVALIDDATA;
        }
        skip_bits(gb, 3); /* reserved */
    } else
        avctx->pix_fmt = AV_PIX_FMT_YUV420P;

    if (s->width < 18)
        return AVERROR_PATCHWELCOME;
    ret = ff_set_dimensions(avctx, s->width, s->height);
    if (ret < 0)
        return ret;
    if (!(avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP)) {
        avctx->width  = visible_width;
        avctx->height = visible_height;
        // translate offsets from theora axis ([0,0] lower left)
        // to normal axis ([0,0] upper left)
        s->offset_x = offset_x;
        s->offset_y = s->height - visible_height - offset_y;
    }

    if (colorspace == 1)
        avctx->color_primaries = AVCOL_PRI_BT470M;
    else if (colorspace == 2)
        avctx->color_primaries = AVCOL_PRI_BT470BG;

    if (colorspace == 1 || colorspace == 2) {
        avctx->colorspace = AVCOL_SPC_BT470BG;
        avctx->color_trc  = AVCOL_TRC_BT709;
    }

    s->theora_header = 1;
    return 0;
}

static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb)
{
    Vp3DecodeContext *s = avctx->priv_data;
    int n, matrices, ret;

    if (!s->theora_header)
        return AVERROR_INVALIDDATA;

    if (s->theora >= 0x030200) {
        n = get_bits(gb, 3);
        /* loop filter limit values table */
        if (n)
            for (int i = 0; i < 64; i++)
                s->filter_limit_values[i] = get_bits(gb, n);
    }

    if (s->theora >= 0x030200)
        n = get_bits(gb, 4) + 1;
    else
        n = 16;
    /* quality threshold table */
    for (int i = 0; i < 64; i++)
        s->coded_ac_scale_factor[i] = get_bits(gb, n);

    if (s->theora >= 0x030200)
        n = get_bits(gb, 4) + 1;
    else
        n = 16;
    /* dc scale factor table */
    for (int i = 0; i < 64; i++)
        s->coded_dc_scale_factor[0][i] =
        s->coded_dc_scale_factor[1][i] = get_bits(gb, n);

    if (s->theora >= 0x030200)
        matrices = get_bits(gb, 9) + 1;
    else
        matrices = 3;

    if (matrices > 384) {
        av_log(avctx, AV_LOG_ERROR, "invalid number of base matrixes\n");
        return -1;
    }

    for (int j = 0; j < matrices; j++)
        for (int i = 0; i < 64; i++)
            s->base_matrix[j][i] = get_bits(gb, 8);

    for (int inter = 0; inter <= 1; inter++) {
        for (int plane = 0; plane <= 2; plane++) {
            int newqr = 1;
            if (inter || plane > 0)
                newqr = get_bits1(gb);
            if (!newqr) {
                int qtj, plj;
                if (inter && get_bits1(gb)) {
                    qtj = 0;
                    plj = plane;
                } else {
                    qtj = (3 * inter + plane - 1) / 3;
                    plj = (plane + 2) % 3;
                }
                s->qr_count[inter][plane] = s->qr_count[qtj][plj];
                memcpy(s->qr_size[inter][plane], s->qr_size[qtj][plj],
                       sizeof(s->qr_size[0][0]));
                memcpy(s->qr_base[inter][plane], s->qr_base[qtj][plj],
                       sizeof(s->qr_base[0][0]));
            } else {
                int qri = 0;
                int qi  = 0;

                for (;;) {
                    int i = get_bits(gb, av_log2(matrices - 1) + 1);
                    if (i >= matrices) {
                        av_log(avctx, AV_LOG_ERROR,
                               "invalid base matrix index\n");
                        return -1;
                    }
                    s->qr_base[inter][plane][qri] = i;
                    if (qi >= 63)
                        break;
                    i = get_bits(gb, av_log2(63 - qi) + 1) + 1;
                    s->qr_size[inter][plane][qri++] = i;
                    qi += i;
                }

                if (qi > 63) {
                    av_log(avctx, AV_LOG_ERROR, "invalid qi %d > 63\n", qi);
                    return -1;
                }
                s->qr_count[inter][plane] = qri;
            }
        }
    }

    /* Huffman tables */
    for (int i = 0; i < FF_ARRAY_ELEMS(s->huffman_table); i++) {
        s->huffman_table[i].nb_entries = 0;
        if ((ret = read_huffman_tree(&s->huffman_table[i], gb, 0, avctx)) < 0)
            return ret;
    }

    s->theora_tables = 1;

    return 0;
}

static av_cold int theora_decode_init(AVCodecContext *avctx)
{
    Vp3DecodeContext *s = avctx->priv_data;
    GetBitContext gb;
    int ptype;
    const uint8_t *header_start[3];
    int header_len[3];
    int ret;

    avctx->pix_fmt = AV_PIX_FMT_YUV420P;

    s->theora = 1;

    if (!avctx->extradata_size) {
        av_log(avctx, AV_LOG_ERROR, "Missing extradata!\n");
        return -1;
    }

    if (avpriv_split_xiph_headers(avctx->extradata, avctx->extradata_size,
                                  42, header_start, header_len) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Corrupt extradata\n");
        return -1;
    }

    for (int i = 0; i < 3; i++) {
        if (header_len[i] <= 0)
            continue;
        ret = init_get_bits8(&gb, header_start[i], header_len[i]);
        if (ret < 0)
            return ret;

        ptype = get_bits(&gb, 8);

        if (!(ptype & 0x80)) {
            av_log(avctx, AV_LOG_ERROR, "Invalid extradata!\n");
//          return -1;
        }

        // FIXME: Check for this as well.
        skip_bits_long(&gb, 6 * 8); /* "theora" */

        switch (ptype) {
        case 0x80:
            if (theora_decode_header(avctx, &gb) < 0)
                return -1;
            break;
        case 0x81:
// FIXME: is this needed? it breaks sometimes
//            theora_decode_comments(avctx, gb);
            break;
        case 0x82:
            if (theora_decode_tables(avctx, &gb))
                return -1;
            break;
        default:
            av_log(avctx, AV_LOG_ERROR,
                   "Unknown Theora config packet: %d\n", ptype & ~0x80);
            break;
        }
        if (ptype != 0x81 && get_bits_left(&gb) >= 8U)
            av_log(avctx, AV_LOG_WARNING,
                   "%d bits left in packet %X\n",
                   get_bits_left(&gb), ptype);
        if (s->theora < 0x030200)
            break;
    }

    return vp3_decode_init(avctx);
}

const FFCodec ff_theora_decoder = {
    .p.name                = "theora",
    CODEC_LONG_NAME("Theora"),
    .p.type                = AVMEDIA_TYPE_VIDEO,
    .p.id                  = AV_CODEC_ID_THEORA,
    .priv_data_size        = sizeof(Vp3DecodeContext),
    .init                  = theora_decode_init,
    .close                 = vp3_decode_end,
    FF_CODEC_DECODE_CB(vp3_decode_frame),
    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
                             AV_CODEC_CAP_FRAME_THREADS,
    .flush                 = vp3_decode_flush,
    UPDATE_THREAD_CONTEXT(vp3_update_thread_context),
    .caps_internal         = FF_CODEC_CAP_INIT_CLEANUP |
                             FF_CODEC_CAP_EXPORTS_CROPPING |
                             FF_CODEC_CAP_USES_PROGRESSFRAMES,
};
#endif

const FFCodec ff_vp3_decoder = {
    .p.name                = "vp3",
    CODEC_LONG_NAME("On2 VP3"),
    .p.type                = AVMEDIA_TYPE_VIDEO,
    .p.id                  = AV_CODEC_ID_VP3,
    .priv_data_size        = sizeof(Vp3DecodeContext),
    .init                  = vp3_decode_init,
    .close                 = vp3_decode_end,
    FF_CODEC_DECODE_CB(vp3_decode_frame),
    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
                             AV_CODEC_CAP_FRAME_THREADS,
    .flush                 = vp3_decode_flush,
    UPDATE_THREAD_CONTEXT(vp3_update_thread_context),
    .caps_internal         = FF_CODEC_CAP_INIT_CLEANUP |
                             FF_CODEC_CAP_USES_PROGRESSFRAMES,
};

#if CONFIG_VP4_DECODER
const FFCodec ff_vp4_decoder = {
    .p.name                = "vp4",
    CODEC_LONG_NAME("On2 VP4"),
    .p.type                = AVMEDIA_TYPE_VIDEO,
    .p.id                  = AV_CODEC_ID_VP4,
    .priv_data_size        = sizeof(Vp3DecodeContext),
    .init                  = vp3_decode_init,
    .close                 = vp3_decode_end,
    FF_CODEC_DECODE_CB(vp3_decode_frame),
    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
                             AV_CODEC_CAP_FRAME_THREADS,
    .flush                 = vp3_decode_flush,
    UPDATE_THREAD_CONTEXT(vp3_update_thread_context),
    .caps_internal         = FF_CODEC_CAP_INIT_CLEANUP |
                             FF_CODEC_CAP_USES_PROGRESSFRAMES,
};
#endif
