/*
 * RV30/40 decoder common data
 * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * RV30/40 decoder common data
 */

#include "libavutil/imgutils.h"
#include "libavutil/internal.h"

#include "avcodec.h"
#include "error_resilience.h"
#include "mpegvideo.h"
#include "golomb.h"
#include "internal.h"
#include "mathops.h"
#include "rectangle.h"
#include "thread.h"

#include "rv34vlc.h"
#include "rv34data.h"
#include "rv34.h"

static inline void ZERO8x2(void* dst, int stride)
{
    fill_rectangle(dst,                 1, 2, stride, 0, 4);
    fill_rectangle(((uint8_t*)(dst))+4, 1, 2, stride, 0, 4);
}

/** translation of RV30/40 macroblock types to lavc ones */
static const int rv34_mb_type_to_lavc[12] = {
    MB_TYPE_INTRA,
    MB_TYPE_INTRA16x16              | MB_TYPE_SEPARATE_DC,
    MB_TYPE_16x16   | MB_TYPE_L0,
    MB_TYPE_8x8     | MB_TYPE_L0,
    MB_TYPE_16x16   | MB_TYPE_L0,
    MB_TYPE_16x16   | MB_TYPE_L1,
    MB_TYPE_SKIP,
    MB_TYPE_DIRECT2 | MB_TYPE_16x16,
    MB_TYPE_16x8    | MB_TYPE_L0,
    MB_TYPE_8x16    | MB_TYPE_L0,
    MB_TYPE_16x16   | MB_TYPE_L0L1,
    MB_TYPE_16x16   | MB_TYPE_L0    | MB_TYPE_SEPARATE_DC
};


static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];

static int rv34_decode_mv(RV34DecContext *r, int block_type);

/**
 * @name RV30/40 VLC generating functions
 * @{
 */

static const int table_offs[] = {
      0,   1818,   3622,   4144,   4698,   5234,   5804,   5868,   5900,   5932,
   5996,   6252,   6316,   6348,   6380,   7674,   8944,  10274,  11668,  12250,
  14060,  15846,  16372,  16962,  17512,  18148,  18180,  18212,  18244,  18308,
  18564,  18628,  18660,  18692,  20036,  21314,  22648,  23968,  24614,  26384,
  28190,  28736,  29366,  29938,  30608,  30640,  30672,  30704,  30768,  31024,
  31088,  31120,  31184,  32570,  33898,  35236,  36644,  37286,  39020,  40802,
  41368,  42052,  42692,  43348,  43380,  43412,  43444,  43476,  43604,  43668,
  43700,  43732,  45100,  46430,  47778,  49160,  49802,  51550,  53340,  53972,
  54648,  55348,  55994,  56122,  56154,  56186,  56218,  56346,  56410,  56442,
  56474,  57878,  59290,  60636,  62036,  62682,  64460,  64524,  64588,  64716,
  64844,  66076,  67466,  67978,  68542,  69064,  69648,  70296,  72010,  72074,
  72138,  72202,  72330,  73572,  74936,  75454,  76030,  76566,  77176,  77822,
  79582,  79646,  79678,  79742,  79870,  81180,  82536,  83064,  83672,  84242,
  84934,  85576,  87384,  87448,  87480,  87544,  87672,  88982,  90340,  90902,
  91598,  92182,  92846,  93488,  95246,  95278,  95310,  95374,  95502,  96878,
  98266,  98848,  99542, 100234, 100884, 101524, 103320, 103352, 103384, 103416,
 103480, 104874, 106222, 106910, 107584, 108258, 108902, 109544, 111366, 111398,
 111430, 111462, 111494, 112878, 114320, 114988, 115660, 116310, 116950, 117592
};

static VLC_TYPE table_data[117592][2];

/**
 * Generate VLC from codeword lengths.
 * @param bits   codeword lengths (zeroes are accepted)
 * @param size   length of input data
 * @param vlc    output VLC
 * @param insyms symbols for input codes (NULL for default ones)
 * @param num    VLC table number (for static initialization)
 */
static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms,
                         const int num)
{
    int i;
    int counts[17] = {0}, codes[17];
    uint16_t cw[MAX_VLC_SIZE], syms[MAX_VLC_SIZE];
    uint8_t bits2[MAX_VLC_SIZE];
    int maxbits = 0, realsize = 0;

    for(i = 0; i < size; i++){
        if(bits[i]){
            bits2[realsize] = bits[i];
            syms[realsize] = insyms ? insyms[i] : i;
            realsize++;
            maxbits = FFMAX(maxbits, bits[i]);
            counts[bits[i]]++;
        }
    }

    codes[0] = 0;
    for(i = 0; i < 16; i++)
        codes[i+1] = (codes[i] + counts[i]) << 1;
    for(i = 0; i < realsize; i++)
        cw[i] = codes[bits2[i]]++;

    vlc->table = &table_data[table_offs[num]];
    vlc->table_allocated = table_offs[num + 1] - table_offs[num];
    ff_init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize,
                       bits2, 1, 1,
                       cw,    2, 2,
                       syms,  2, 2, INIT_VLC_USE_NEW_STATIC);
}

/**
 * Initialize all tables.
 */
static av_cold void rv34_init_tables(void)
{
    int i, j, k;

    for(i = 0; i < NUM_INTRA_TABLES; i++){
        for(j = 0; j < 2; j++){
            rv34_gen_vlc(rv34_table_intra_cbppat   [i][j], CBPPAT_VLC_SIZE,   &intra_vlcs[i].cbppattern[j],     NULL, 19*i + 0 + j);
            rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j], NULL, 19*i + 2 + j);
            rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j],  NULL, 19*i + 4 + j);
            for(k = 0; k < 4; k++){
                rv34_gen_vlc(rv34_table_intra_cbp[i][j+k*2],  CBP_VLC_SIZE,   &intra_vlcs[i].cbp[j][k],         rv34_cbp_code, 19*i + 6 + j*4 + k);
            }
        }
        for(j = 0; j < 4; j++){
            rv34_gen_vlc(rv34_table_intra_firstpat[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j], NULL, 19*i + 14 + j);
        }
        rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL, 19*i + 18);
    }

    for(i = 0; i < NUM_INTER_TABLES; i++){
        rv34_gen_vlc(rv34_inter_cbppat[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0], NULL, i*12 + 95);
        for(j = 0; j < 4; j++){
            rv34_gen_vlc(rv34_inter_cbp[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j], rv34_cbp_code, i*12 + 96 + j);
        }
        for(j = 0; j < 2; j++){
            rv34_gen_vlc(rv34_table_inter_firstpat [i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j],  NULL, i*12 + 100 + j);
            rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j], NULL, i*12 + 102 + j);
            rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j],  NULL, i*12 + 104 + j);
        }
        rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL, i*12 + 106);
    }
}

/** @} */ // vlc group

/**
 * @name RV30/40 4x4 block decoding functions
 * @{
 */

/**
 * Decode coded block pattern.
 */
static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table)
{
    int pattern, code, cbp=0;
    int ones;
    static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000};
    static const int shifts[4] = { 0, 2, 8, 10 };
    const int *curshift = shifts;
    int i, t, mask;

    code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2);
    pattern = code & 0xF;
    code >>= 4;

    ones = rv34_count_ones[pattern];

    for(mask = 8; mask; mask >>= 1, curshift++){
        if(pattern & mask)
            cbp |= get_vlc2(gb, vlc->cbp[table][ones].table, vlc->cbp[table][ones].bits, 1) << curshift[0];
    }

    for(i = 0; i < 4; i++){
        t = (modulo_three_table[code] >> (6 - 2*i)) & 3;
        if(t == 1)
            cbp |= cbp_masks[get_bits1(gb)] << i;
        if(t == 2)
            cbp |= cbp_masks[2] << i;
    }
    return cbp;
}

/**
 * Get one coefficient value from the bitstream and store it.
 */
static inline void decode_coeff(int16_t *dst, int coef, int esc, GetBitContext *gb, VLC* vlc, int q)
{
    if(coef){
        if(coef == esc){
            coef = get_vlc2(gb, vlc->table, 9, 2);
            if(coef > 23){
                coef -= 23;
                coef = 22 + ((1 << coef) | get_bits(gb, coef));
            }
            coef += esc;
        }
        if(get_bits1(gb))
            coef = -coef;
        *dst = (coef*q + 8) >> 4;
    }
}

/**
 * Decode 2x2 subblock of coefficients.
 */
static inline void decode_subblock(int16_t *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, int q)
{
    int flags = modulo_three_table[code];

    decode_coeff(    dst+0*4+0, (flags >> 6)    , 3, gb, vlc, q);
    if(is_block2){
        decode_coeff(dst+1*4+0, (flags >> 4) & 3, 2, gb, vlc, q);
        decode_coeff(dst+0*4+1, (flags >> 2) & 3, 2, gb, vlc, q);
    }else{
        decode_coeff(dst+0*4+1, (flags >> 4) & 3, 2, gb, vlc, q);
        decode_coeff(dst+1*4+0, (flags >> 2) & 3, 2, gb, vlc, q);
    }
    decode_coeff(    dst+1*4+1, (flags >> 0) & 3, 2, gb, vlc, q);
}

/**
 * Decode a single coefficient.
 */
static inline void decode_subblock1(int16_t *dst, int code, GetBitContext *gb, VLC *vlc, int q)
{
    int coeff = modulo_three_table[code] >> 6;
    decode_coeff(dst, coeff, 3, gb, vlc, q);
}

static inline void decode_subblock3(int16_t *dst, int code, GetBitContext *gb, VLC *vlc,
                                    int q_dc, int q_ac1, int q_ac2)
{
    int flags = modulo_three_table[code];

    decode_coeff(dst+0*4+0, (flags >> 6)    , 3, gb, vlc, q_dc);
    decode_coeff(dst+0*4+1, (flags >> 4) & 3, 2, gb, vlc, q_ac1);
    decode_coeff(dst+1*4+0, (flags >> 2) & 3, 2, gb, vlc, q_ac1);
    decode_coeff(dst+1*4+1, (flags >> 0) & 3, 2, gb, vlc, q_ac2);
}

/**
 * Decode coefficients for 4x4 block.
 *
 * This is done by filling 2x2 subblocks with decoded coefficients
 * in this order (the same for subblocks and subblock coefficients):
 *  o--o
 *    /
 *   /
 *  o--o
 */

static int rv34_decode_block(int16_t *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc, int q_dc, int q_ac1, int q_ac2)
{
    int code, pattern, has_ac = 1;

    code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2);

    pattern = code & 0x7;

    code >>= 3;

    if (modulo_three_table[code] & 0x3F) {
        decode_subblock3(dst, code, gb, &rvlc->coefficient, q_dc, q_ac1, q_ac2);
    } else {
        decode_subblock1(dst, code, gb, &rvlc->coefficient, q_dc);
        if (!pattern)
            return 0;
        has_ac = 0;
    }

    if(pattern & 4){
        code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
        decode_subblock(dst + 4*0+2, code, 0, gb, &rvlc->coefficient, q_ac2);
    }
    if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block
        code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
        decode_subblock(dst + 4*2+0, code, 1, gb, &rvlc->coefficient, q_ac2);
    }
    if(pattern & 1){
        code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
        decode_subblock(dst + 4*2+2, code, 0, gb, &rvlc->coefficient, q_ac2);
    }
    return has_ac | pattern;
}

/**
 * @name RV30/40 bitstream parsing
 * @{
 */

/**
 * Decode starting slice position.
 * @todo Maybe replace with ff_h263_decode_mba() ?
 */
int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size)
{
    int i;
    for(i = 0; i < 5; i++)
        if(rv34_mb_max_sizes[i] >= mb_size - 1)
            break;
    return rv34_mb_bits_sizes[i];
}

/**
 * Select VLC set for decoding from current quantizer, modifier and frame type.
 */
static inline RV34VLC* choose_vlc_set(int quant, int mod, int type)
{
    if(mod == 2 && quant < 19) quant += 10;
    else if(mod && quant < 26) quant += 5;
    return type ? &inter_vlcs[rv34_quant_to_vlc_set[1][av_clip(quant, 0, 30)]]
                : &intra_vlcs[rv34_quant_to_vlc_set[0][av_clip(quant, 0, 30)]];
}

/**
 * Decode intra macroblock header and return CBP in case of success, -1 otherwise.
 */
static int rv34_decode_intra_mb_header(RV34DecContext *r, int8_t *intra_types)
{
    MpegEncContext *s = &r->s;
    GetBitContext *gb = &s->gb;
    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
    int t;

    r->is16 = get_bits1(gb);
    if(r->is16){
        s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA16x16;
        r->block_type = RV34_MB_TYPE_INTRA16x16;
        t = get_bits(gb, 2);
        fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
        r->luma_vlc   = 2;
    }else{
        if(!r->rv30){
            if(!get_bits1(gb))
                av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
        }
        s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA;
        r->block_type = RV34_MB_TYPE_INTRA;
        if(r->decode_intra_types(r, gb, intra_types) < 0)
            return -1;
        r->luma_vlc   = 1;
    }

    r->chroma_vlc = 0;
    r->cur_vlcs   = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);

    return rv34_decode_cbp(gb, r->cur_vlcs, r->is16);
}

/**
 * Decode inter macroblock header and return CBP in case of success, -1 otherwise.
 */
static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types)
{
    MpegEncContext *s = &r->s;
    GetBitContext *gb = &s->gb;
    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
    int i, t;

    r->block_type = r->decode_mb_info(r);
    if(r->block_type == -1)
        return -1;
    s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
    r->mb_type[mb_pos] = r->block_type;
    if(r->block_type == RV34_MB_SKIP){
        if(s->pict_type == AV_PICTURE_TYPE_P)
            r->mb_type[mb_pos] = RV34_MB_P_16x16;
        if(s->pict_type == AV_PICTURE_TYPE_B)
            r->mb_type[mb_pos] = RV34_MB_B_DIRECT;
    }
    r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]);
    rv34_decode_mv(r, r->block_type);
    if(r->block_type == RV34_MB_SKIP){
        fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0]));
        return 0;
    }
    r->chroma_vlc = 1;
    r->luma_vlc   = 0;

    if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
        if(r->is16){
            t = get_bits(gb, 2);
            fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
            r->luma_vlc   = 2;
        }else{
            if(r->decode_intra_types(r, gb, intra_types) < 0)
                return -1;
            r->luma_vlc   = 1;
        }
        r->chroma_vlc = 0;
        r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
    }else{
        for(i = 0; i < 16; i++)
            intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0;
        r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
        if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){
            r->is16 = 1;
            r->chroma_vlc = 1;
            r->luma_vlc   = 2;
            r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
        }
    }

    return rv34_decode_cbp(gb, r->cur_vlcs, r->is16);
}

/** @} */ //bitstream functions

/**
 * @name motion vector related code (prediction, reconstruction, motion compensation)
 * @{
 */

/** macroblock partition width in 8x8 blocks */
static const uint8_t part_sizes_w[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2 };

/** macroblock partition height in 8x8 blocks */
static const uint8_t part_sizes_h[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2 };

/** availability index for subblocks */
static const uint8_t avail_indexes[4] = { 6, 7, 10, 11 };

/**
 * motion vector prediction
 *
 * Motion prediction performed for the block by using median prediction of
 * motion vectors from the left, top and right top blocks but in corner cases
 * some other vectors may be used instead.
 */
static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int dmv_no)
{
    MpegEncContext *s = &r->s;
    int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
    int A[2] = {0}, B[2], C[2];
    int i, j;
    int mx, my;
    int* avail = r->avail_cache + avail_indexes[subblock_no];
    int c_off = part_sizes_w[block_type];

    mv_pos += (subblock_no & 1) + (subblock_no >> 1)*s->b8_stride;
    if(subblock_no == 3)
        c_off = -1;

    if(avail[-1]){
        A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0];
        A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1];
    }
    if(avail[-4]){
        B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0];
        B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1];
    }else{
        B[0] = A[0];
        B[1] = A[1];
    }
    if(!avail[c_off-4]){
        if(avail[-4] && (avail[-1] || r->rv30)){
            C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0];
            C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1];
        }else{
            C[0] = A[0];
            C[1] = A[1];
        }
    }else{
        C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][0];
        C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][1];
    }
    mx = mid_pred(A[0], B[0], C[0]);
    my = mid_pred(A[1], B[1], C[1]);
    mx += r->dmv[dmv_no][0];
    my += r->dmv[dmv_no][1];
    for(j = 0; j < part_sizes_h[block_type]; j++){
        for(i = 0; i < part_sizes_w[block_type]; i++){
            s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
            s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
        }
    }
}

#define GET_PTS_DIFF(a, b) ((a - b + 8192) & 0x1FFF)

/**
 * Calculate motion vector component that should be added for direct blocks.
 */
static int calc_add_mv(RV34DecContext *r, int dir, int val)
{
    int mul = dir ? -r->mv_weight2 : r->mv_weight1;

    return (val * mul + 0x2000) >> 14;
}

/**
 * Predict motion vector for B-frame macroblock.
 */
static inline void rv34_pred_b_vector(int A[2], int B[2], int C[2],
                                      int A_avail, int B_avail, int C_avail,
                                      int *mx, int *my)
{
    if(A_avail + B_avail + C_avail != 3){
        *mx = A[0] + B[0] + C[0];
        *my = A[1] + B[1] + C[1];
        if(A_avail + B_avail + C_avail == 2){
            *mx /= 2;
            *my /= 2;
        }
    }else{
        *mx = mid_pred(A[0], B[0], C[0]);
        *my = mid_pred(A[1], B[1], C[1]);
    }
}

/**
 * motion vector prediction for B-frames
 */
static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
{
    MpegEncContext *s = &r->s;
    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
    int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
    int A[2] = { 0 }, B[2] = { 0 }, C[2] = { 0 };
    int has_A = 0, has_B = 0, has_C = 0;
    int mx, my;
    int i, j;
    Picture *cur_pic = s->current_picture_ptr;
    const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0;
    int type = cur_pic->mb_type[mb_pos];

    if((r->avail_cache[6-1] & type) & mask){
        A[0] = cur_pic->motion_val[dir][mv_pos - 1][0];
        A[1] = cur_pic->motion_val[dir][mv_pos - 1][1];
        has_A = 1;
    }
    if((r->avail_cache[6-4] & type) & mask){
        B[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][0];
        B[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][1];
        has_B = 1;
    }
    if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){
        C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][0];
        C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][1];
        has_C = 1;
    }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){
        C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][0];
        C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][1];
        has_C = 1;
    }

    rv34_pred_b_vector(A, B, C, has_A, has_B, has_C, &mx, &my);

    mx += r->dmv[dir][0];
    my += r->dmv[dir][1];

    for(j = 0; j < 2; j++){
        for(i = 0; i < 2; i++){
            cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
            cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
        }
    }
    if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){
        ZERO8x2(cur_pic->motion_val[!dir][mv_pos], s->b8_stride);
    }
}

/**
 * motion vector prediction - RV3 version
 */
static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
{
    MpegEncContext *s = &r->s;
    int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
    int A[2] = {0}, B[2], C[2];
    int i, j, k;
    int mx, my;
    int* avail = r->avail_cache + avail_indexes[0];

    if(avail[-1]){
        A[0] = s->current_picture_ptr->motion_val[0][mv_pos - 1][0];
        A[1] = s->current_picture_ptr->motion_val[0][mv_pos - 1][1];
    }
    if(avail[-4]){
        B[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][0];
        B[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][1];
    }else{
        B[0] = A[0];
        B[1] = A[1];
    }
    if(!avail[-4 + 2]){
        if(avail[-4] && (avail[-1])){
            C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][0];
            C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][1];
        }else{
            C[0] = A[0];
            C[1] = A[1];
        }
    }else{
        C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][0];
        C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][1];
    }
    mx = mid_pred(A[0], B[0], C[0]);
    my = mid_pred(A[1], B[1], C[1]);
    mx += r->dmv[0][0];
    my += r->dmv[0][1];
    for(j = 0; j < 2; j++){
        for(i = 0; i < 2; i++){
            for(k = 0; k < 2; k++){
                s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
                s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
            }
        }
    }
}

static const int chroma_coeffs[3] = { 0, 3, 5 };

/**
 * generic motion compensation function
 *
 * @param r decoder context
 * @param block_type type of the current block
 * @param xoff horizontal offset from the start of the current block
 * @param yoff vertical offset from the start of the current block
 * @param mv_off offset to the motion vector information
 * @param width width of the current partition in 8x8 blocks
 * @param height height of the current partition in 8x8 blocks
 * @param dir motion compensation direction (i.e. from the last or the next reference frame)
 * @param thirdpel motion vectors are specified in 1/3 of pixel
 * @param qpel_mc a set of functions used to perform luma motion compensation
 * @param chroma_mc a set of functions used to perform chroma motion compensation
 */
static inline void rv34_mc(RV34DecContext *r, const int block_type,
                          const int xoff, const int yoff, int mv_off,
                          const int width, const int height, int dir,
                          const int thirdpel, int weighted,
                          qpel_mc_func (*qpel_mc)[16],
                          h264_chroma_mc_func (*chroma_mc))
{
    MpegEncContext *s = &r->s;
    uint8_t *Y, *U, *V, *srcY, *srcU, *srcV;
    int dxy, mx, my, umx, umy, lx, ly, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
    int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + mv_off;
    int is16x16 = 1;

    if(thirdpel){
        int chroma_mx, chroma_my;
        mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
        my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
        lx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
        ly = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
        chroma_mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
        chroma_my = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
        umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24);
        umy = (chroma_my + (3 << 24)) / 3 - (1 << 24);
        uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3];
        uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3];
    }else{
        int cx, cy;
        mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] >> 2;
        my = s->current_picture_ptr->motion_val[dir][mv_pos][1] >> 2;
        lx = s->current_picture_ptr->motion_val[dir][mv_pos][0] & 3;
        ly = s->current_picture_ptr->motion_val[dir][mv_pos][1] & 3;
        cx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
        cy = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
        umx = cx >> 2;
        umy = cy >> 2;
        uvmx = (cx & 3) << 1;
        uvmy = (cy & 3) << 1;
        //due to some flaw RV40 uses the same MC compensation routine for H2V2 and H3V3
        if(uvmx == 6 && uvmy == 6)
            uvmx = uvmy = 4;
    }

    if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
        /* wait for the referenced mb row to be finished */
        int mb_row = s->mb_y + ((yoff + my + 5 + 8 * height) >> 4);
        ThreadFrame *f = dir ? &s->next_picture_ptr->tf : &s->last_picture_ptr->tf;
        ff_thread_await_progress(f, mb_row, 0);
    }

    dxy = ly*4 + lx;
    srcY = dir ? s->next_picture_ptr->f.data[0] : s->last_picture_ptr->f.data[0];
    srcU = dir ? s->next_picture_ptr->f.data[1] : s->last_picture_ptr->f.data[1];
    srcV = dir ? s->next_picture_ptr->f.data[2] : s->last_picture_ptr->f.data[2];
    src_x = s->mb_x * 16 + xoff + mx;
    src_y = s->mb_y * 16 + yoff + my;
    uvsrc_x = s->mb_x * 8 + (xoff >> 1) + umx;
    uvsrc_y = s->mb_y * 8 + (yoff >> 1) + umy;
    srcY += src_y * s->linesize + src_x;
    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
    if(s->h_edge_pos - (width << 3) < 6 || s->v_edge_pos - (height << 3) < 6 ||
       (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4 ||
       (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4) {
        uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize;

        srcY -= 2 + 2*s->linesize;
        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6,
                            src_x - 2, src_y - 2, s->h_edge_pos, s->v_edge_pos);
        srcY = s->edge_emu_buffer + 2 + 2*s->linesize;
        s->vdsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1,
                            uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
        s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1,
                            uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
        srcU = uvbuf;
        srcV = uvbuf + 16;
    }
    if(!weighted){
        Y = s->dest[0] + xoff      + yoff     *s->linesize;
        U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
        V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
    }else{
        Y = r->tmp_b_block_y [dir]     +  xoff     +  yoff    *s->linesize;
        U = r->tmp_b_block_uv[dir*2]   + (xoff>>1) + (yoff>>1)*s->uvlinesize;
        V = r->tmp_b_block_uv[dir*2+1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
    }

    if(block_type == RV34_MB_P_16x8){
        qpel_mc[1][dxy](Y, srcY, s->linesize);
        Y    += 8;
        srcY += 8;
    }else if(block_type == RV34_MB_P_8x16){
        qpel_mc[1][dxy](Y, srcY, s->linesize);
        Y    += 8 * s->linesize;
        srcY += 8 * s->linesize;
    }
    is16x16 = (block_type != RV34_MB_P_8x8) && (block_type != RV34_MB_P_16x8) && (block_type != RV34_MB_P_8x16);
    qpel_mc[!is16x16][dxy](Y, srcY, s->linesize);
    chroma_mc[2-width]   (U, srcU, s->uvlinesize, height*4, uvmx, uvmy);
    chroma_mc[2-width]   (V, srcV, s->uvlinesize, height*4, uvmx, uvmy);
}

static void rv34_mc_1mv(RV34DecContext *r, const int block_type,
                        const int xoff, const int yoff, int mv_off,
                        const int width, const int height, int dir)
{
    rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30, 0,
            r->rdsp.put_pixels_tab,
            r->rdsp.put_chroma_pixels_tab);
}

static void rv4_weight(RV34DecContext *r)
{
    r->rdsp.rv40_weight_pixels_tab[r->scaled_weight][0](r->s.dest[0],
                                                        r->tmp_b_block_y[0],
                                                        r->tmp_b_block_y[1],
                                                        r->weight1,
                                                        r->weight2,
                                                        r->s.linesize);
    r->rdsp.rv40_weight_pixels_tab[r->scaled_weight][1](r->s.dest[1],
                                                        r->tmp_b_block_uv[0],
                                                        r->tmp_b_block_uv[2],
                                                        r->weight1,
                                                        r->weight2,
                                                        r->s.uvlinesize);
    r->rdsp.rv40_weight_pixels_tab[r->scaled_weight][1](r->s.dest[2],
                                                        r->tmp_b_block_uv[1],
                                                        r->tmp_b_block_uv[3],
                                                        r->weight1,
                                                        r->weight2,
                                                        r->s.uvlinesize);
}

static void rv34_mc_2mv(RV34DecContext *r, const int block_type)
{
    int weighted = !r->rv30 && block_type != RV34_MB_B_BIDIR && r->weight1 != 8192;

    rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30, weighted,
            r->rdsp.put_pixels_tab,
            r->rdsp.put_chroma_pixels_tab);
    if(!weighted){
        rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 0,
                r->rdsp.avg_pixels_tab,
                r->rdsp.avg_chroma_pixels_tab);
    }else{
        rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 1,
                r->rdsp.put_pixels_tab,
                r->rdsp.put_chroma_pixels_tab);
        rv4_weight(r);
    }
}

static void rv34_mc_2mv_skip(RV34DecContext *r)
{
    int i, j;
    int weighted = !r->rv30 && r->weight1 != 8192;

    for(j = 0; j < 2; j++)
        for(i = 0; i < 2; i++){
             rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30,
                     weighted,
                     r->rdsp.put_pixels_tab,
                     r->rdsp.put_chroma_pixels_tab);
             rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30,
                     weighted,
                     weighted ? r->rdsp.put_pixels_tab : r->rdsp.avg_pixels_tab,
                     weighted ? r->rdsp.put_chroma_pixels_tab : r->rdsp.avg_chroma_pixels_tab);
        }
    if(weighted)
        rv4_weight(r);
}

/** number of motion vectors in each macroblock type */
static const int num_mvs[RV34_MB_TYPES] = { 0, 0, 1, 4, 1, 1, 0, 0, 2, 2, 2, 1 };

/**
 * Decode motion vector differences
 * and perform motion vector reconstruction and motion compensation.
 */
static int rv34_decode_mv(RV34DecContext *r, int block_type)
{
    MpegEncContext *s = &r->s;
    GetBitContext *gb = &s->gb;
    int i, j, k, l;
    int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
    int next_bt;

    memset(r->dmv, 0, sizeof(r->dmv));
    for(i = 0; i < num_mvs[block_type]; i++){
        r->dmv[i][0] = svq3_get_se_golomb(gb);
        r->dmv[i][1] = svq3_get_se_golomb(gb);
    }
    switch(block_type){
    case RV34_MB_TYPE_INTRA:
    case RV34_MB_TYPE_INTRA16x16:
        ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
        return 0;
    case RV34_MB_SKIP:
        if(s->pict_type == AV_PICTURE_TYPE_P){
            ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
            rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
            break;
        }
    case RV34_MB_B_DIRECT:
        //surprisingly, it uses motion scheme from next reference frame
        /* wait for the current mb row to be finished */
        if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
            ff_thread_await_progress(&s->next_picture_ptr->tf, FFMAX(0, s->mb_y-1), 0);

        next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride];
        if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){
            ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
            ZERO8x2(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
        }else
            for(j = 0; j < 2; j++)
                for(i = 0; i < 2; i++)
                    for(k = 0; k < 2; k++)
                        for(l = 0; l < 2; l++)
                            s->current_picture_ptr->motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k]);
        if(!(IS_16X8(next_bt) || IS_8X16(next_bt) || IS_8X8(next_bt))) //we can use whole macroblock MC
            rv34_mc_2mv(r, block_type);
        else
            rv34_mc_2mv_skip(r);
        ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
        break;
    case RV34_MB_P_16x16:
    case RV34_MB_P_MIX16x16:
        rv34_pred_mv(r, block_type, 0, 0);
        rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
        break;
    case RV34_MB_B_FORWARD:
    case RV34_MB_B_BACKWARD:
        r->dmv[1][0] = r->dmv[0][0];
        r->dmv[1][1] = r->dmv[0][1];
        if(r->rv30)
            rv34_pred_mv_rv3(r, block_type, block_type == RV34_MB_B_BACKWARD);
        else
            rv34_pred_mv_b  (r, block_type, block_type == RV34_MB_B_BACKWARD);
        rv34_mc_1mv     (r, block_type, 0, 0, 0, 2, 2, block_type == RV34_MB_B_BACKWARD);
        break;
    case RV34_MB_P_16x8:
    case RV34_MB_P_8x16:
        rv34_pred_mv(r, block_type, 0, 0);
        rv34_pred_mv(r, block_type, 1 + (block_type == RV34_MB_P_16x8), 1);
        if(block_type == RV34_MB_P_16x8){
            rv34_mc_1mv(r, block_type, 0, 0, 0,            2, 1, 0);
            rv34_mc_1mv(r, block_type, 0, 8, s->b8_stride, 2, 1, 0);
        }
        if(block_type == RV34_MB_P_8x16){
            rv34_mc_1mv(r, block_type, 0, 0, 0, 1, 2, 0);
            rv34_mc_1mv(r, block_type, 8, 0, 1, 1, 2, 0);
        }
        break;
    case RV34_MB_B_BIDIR:
        rv34_pred_mv_b  (r, block_type, 0);
        rv34_pred_mv_b  (r, block_type, 1);
        rv34_mc_2mv     (r, block_type);
        break;
    case RV34_MB_P_8x8:
        for(i=0;i< 4;i++){
            rv34_pred_mv(r, block_type, i, i);
            rv34_mc_1mv (r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1, 0);
        }
        break;
    }

    return 0;
}
/** @} */ // mv group

/**
 * @name Macroblock reconstruction functions
 * @{
 */
/** mapping of RV30/40 intra prediction types to standard H.264 types */
static const int ittrans[9] = {
 DC_PRED, VERT_PRED, HOR_PRED, DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_LEFT_PRED,
 VERT_RIGHT_PRED, VERT_LEFT_PRED, HOR_UP_PRED, HOR_DOWN_PRED,
};

/** mapping of RV30/40 intra 16x16 prediction types to standard H.264 types */
static const int ittrans16[4] = {
 DC_PRED8x8, VERT_PRED8x8, HOR_PRED8x8, PLANE_PRED8x8,
};

/**
 * Perform 4x4 intra prediction.
 */
static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int itype, int up, int left, int down, int right)
{
    uint8_t *prev = dst - stride + 4;
    uint32_t topleft;

    if(!up && !left)
        itype = DC_128_PRED;
    else if(!up){
        if(itype == VERT_PRED) itype = HOR_PRED;
        if(itype == DC_PRED)   itype = LEFT_DC_PRED;
    }else if(!left){
        if(itype == HOR_PRED)  itype = VERT_PRED;
        if(itype == DC_PRED)   itype = TOP_DC_PRED;
        if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
    }
    if(!down){
        if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
        if(itype == HOR_UP_PRED) itype = HOR_UP_PRED_RV40_NODOWN;
        if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN;
    }
    if(!right && up){
        topleft = dst[-stride + 3] * 0x01010101u;
        prev = (uint8_t*)&topleft;
    }
    r->h.pred4x4[itype](dst, prev, stride);
}

static inline int adjust_pred16(int itype, int up, int left)
{
    if(!up && !left)
        itype = DC_128_PRED8x8;
    else if(!up){
        if(itype == PLANE_PRED8x8)itype = HOR_PRED8x8;
        if(itype == VERT_PRED8x8) itype = HOR_PRED8x8;
        if(itype == DC_PRED8x8)   itype = LEFT_DC_PRED8x8;
    }else if(!left){
        if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8;
        if(itype == HOR_PRED8x8)  itype = VERT_PRED8x8;
        if(itype == DC_PRED8x8)   itype = TOP_DC_PRED8x8;
    }
    return itype;
}

static inline void rv34_process_block(RV34DecContext *r,
                                      uint8_t *pdst, int stride,
                                      int fc, int sc, int q_dc, int q_ac)
{
    MpegEncContext *s = &r->s;
    int16_t *ptr = s->block[0];
    int has_ac = rv34_decode_block(ptr, &s->gb, r->cur_vlcs,
                                   fc, sc, q_dc, q_ac, q_ac);
    if(has_ac){
        r->rdsp.rv34_idct_add(pdst, stride, ptr);
    }else{
        r->rdsp.rv34_idct_dc_add(pdst, stride, ptr[0]);
        ptr[0] = 0;
    }
}

static void rv34_output_i16x16(RV34DecContext *r, int8_t *intra_types, int cbp)
{
    LOCAL_ALIGNED_16(int16_t, block16, [16]);
    MpegEncContext *s    = &r->s;
    GetBitContext  *gb   = &s->gb;
    int             q_dc = rv34_qscale_tab[ r->luma_dc_quant_i[s->qscale] ],
                    q_ac = rv34_qscale_tab[s->qscale];
    uint8_t        *dst  = s->dest[0];
    int16_t        *ptr  = s->block[0];
    int i, j, itype, has_ac;

    memset(block16, 0, 16 * sizeof(*block16));

    has_ac = rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac);
    if(has_ac)
        r->rdsp.rv34_inv_transform(block16);
    else
        r->rdsp.rv34_inv_transform_dc(block16);

    itype = ittrans16[intra_types[0]];
    itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
    r->h.pred16x16[itype](dst, s->linesize);

    for(j = 0; j < 4; j++){
        for(i = 0; i < 4; i++, cbp >>= 1){
            int dc = block16[i + j*4];

            if(cbp & 1){
                has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
            }else
                has_ac = 0;

            if(has_ac){
                ptr[0] = dc;
                r->rdsp.rv34_idct_add(dst+4*i, s->linesize, ptr);
            }else
                r->rdsp.rv34_idct_dc_add(dst+4*i, s->linesize, dc);
        }

        dst += 4*s->linesize;
    }

    itype = ittrans16[intra_types[0]];
    if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
    itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);

    q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
    q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];

    for(j = 1; j < 3; j++){
        dst = s->dest[j];
        r->h.pred8x8[itype](dst, s->uvlinesize);
        for(i = 0; i < 4; i++, cbp >>= 1){
            uint8_t *pdst;
            if(!(cbp & 1)) continue;
            pdst   = dst + (i&1)*4 + (i&2)*2*s->uvlinesize;

            rv34_process_block(r, pdst, s->uvlinesize,
                               r->chroma_vlc, 1, q_dc, q_ac);
        }
    }
}

static void rv34_output_intra(RV34DecContext *r, int8_t *intra_types, int cbp)
{
    MpegEncContext *s   = &r->s;
    uint8_t        *dst = s->dest[0];
    int      avail[6*8] = {0};
    int i, j, k;
    int idx, q_ac, q_dc;

    // Set neighbour information.
    if(r->avail_cache[1])
        avail[0] = 1;
    if(r->avail_cache[2])
        avail[1] = avail[2] = 1;
    if(r->avail_cache[3])
        avail[3] = avail[4] = 1;
    if(r->avail_cache[4])
        avail[5] = 1;
    if(r->avail_cache[5])
        avail[8] = avail[16] = 1;
    if(r->avail_cache[9])
        avail[24] = avail[32] = 1;

    q_ac = rv34_qscale_tab[s->qscale];
    for(j = 0; j < 4; j++){
        idx = 9 + j*8;
        for(i = 0; i < 4; i++, cbp >>= 1, dst += 4, idx++){
            rv34_pred_4x4_block(r, dst, s->linesize, ittrans[intra_types[i]], avail[idx-8], avail[idx-1], avail[idx+7], avail[idx-7]);
            avail[idx] = 1;
            if(!(cbp & 1)) continue;

            rv34_process_block(r, dst, s->linesize,
                               r->luma_vlc, 0, q_ac, q_ac);
        }
        dst += s->linesize * 4 - 4*4;
        intra_types += r->intra_types_stride;
    }

    intra_types -= r->intra_types_stride * 4;

    q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
    q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];

    for(k = 0; k < 2; k++){
        dst = s->dest[1+k];
        fill_rectangle(r->avail_cache + 6, 2, 2, 4, 0, 4);

        for(j = 0; j < 2; j++){
            int* acache = r->avail_cache + 6 + j*4;
            for(i = 0; i < 2; i++, cbp >>= 1, acache++){
                int itype = ittrans[intra_types[i*2+j*2*r->intra_types_stride]];
                rv34_pred_4x4_block(r, dst+4*i, s->uvlinesize, itype, acache[-4], acache[-1], !i && !j, acache[-3]);
                acache[0] = 1;

                if(!(cbp&1)) continue;

                rv34_process_block(r, dst + 4*i, s->uvlinesize,
                                   r->chroma_vlc, 1, q_dc, q_ac);
            }

            dst += 4*s->uvlinesize;
        }
    }
}

static int is_mv_diff_gt_3(int16_t (*motion_val)[2], int step)
{
    int d;
    d = motion_val[0][0] - motion_val[-step][0];
    if(d < -3 || d > 3)
        return 1;
    d = motion_val[0][1] - motion_val[-step][1];
    if(d < -3 || d > 3)
        return 1;
    return 0;
}

static int rv34_set_deblock_coef(RV34DecContext *r)
{
    MpegEncContext *s = &r->s;
    int hmvmask = 0, vmvmask = 0, i, j;
    int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
    int16_t (*motion_val)[2] = &s->current_picture_ptr->motion_val[0][midx];
    for(j = 0; j < 16; j += 8){
        for(i = 0; i < 2; i++){
            if(is_mv_diff_gt_3(motion_val + i, 1))
                vmvmask |= 0x11 << (j + i*2);
            if((j || s->mb_y) && is_mv_diff_gt_3(motion_val + i, s->b8_stride))
                hmvmask |= 0x03 << (j + i*2);
        }
        motion_val += s->b8_stride;
    }
    if(s->first_slice_line)
        hmvmask &= ~0x000F;
    if(!s->mb_x)
        vmvmask &= ~0x1111;
    if(r->rv30){ //RV30 marks both subblocks on the edge for filtering
        vmvmask |= (vmvmask & 0x4444) >> 1;
        hmvmask |= (hmvmask & 0x0F00) >> 4;
        if(s->mb_x)
            r->deblock_coefs[s->mb_x - 1 + s->mb_y*s->mb_stride] |= (vmvmask & 0x1111) << 3;
        if(!s->first_slice_line)
            r->deblock_coefs[s->mb_x + (s->mb_y - 1)*s->mb_stride] |= (hmvmask & 0xF) << 12;
    }
    return hmvmask | vmvmask;
}

static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types)
{
    MpegEncContext *s   = &r->s;
    GetBitContext  *gb  = &s->gb;
    uint8_t        *dst = s->dest[0];
    int16_t        *ptr = s->block[0];
    int          mb_pos = s->mb_x + s->mb_y * s->mb_stride;
    int cbp, cbp2;
    int q_dc, q_ac, has_ac;
    int i, j;
    int dist;

    // Calculate which neighbours are available. Maybe it's worth optimizing too.
    memset(r->avail_cache, 0, sizeof(r->avail_cache));
    fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4);
    dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
    if(s->mb_x && dist)
        r->avail_cache[5] =
        r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
    if(dist >= s->mb_width)
        r->avail_cache[2] =
        r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
    if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
        r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
    if(s->mb_x && dist > s->mb_width)
        r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];

    s->qscale = r->si.quant;
    cbp = cbp2 = rv34_decode_inter_mb_header(r, intra_types);
    r->cbp_luma  [mb_pos] = cbp;
    r->cbp_chroma[mb_pos] = cbp >> 16;
    r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos];
    s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;

    if(cbp == -1)
        return -1;

    if (IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
        if(r->is16) rv34_output_i16x16(r, intra_types, cbp);
        else        rv34_output_intra(r, intra_types, cbp);
        return 0;
    }

    if(r->is16){
        // Only for RV34_MB_P_MIX16x16
        LOCAL_ALIGNED_16(int16_t, block16, [16]);
        memset(block16, 0, 16 * sizeof(*block16));
        q_dc = rv34_qscale_tab[ r->luma_dc_quant_p[s->qscale] ];
        q_ac = rv34_qscale_tab[s->qscale];
        if (rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac))
            r->rdsp.rv34_inv_transform(block16);
        else
            r->rdsp.rv34_inv_transform_dc(block16);

        q_ac = rv34_qscale_tab[s->qscale];

        for(j = 0; j < 4; j++){
            for(i = 0; i < 4; i++, cbp >>= 1){
                int      dc   = block16[i + j*4];

                if(cbp & 1){
                    has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
                }else
                    has_ac = 0;

                if(has_ac){
                    ptr[0] = dc;
                    r->rdsp.rv34_idct_add(dst+4*i, s->linesize, ptr);
                }else
                    r->rdsp.rv34_idct_dc_add(dst+4*i, s->linesize, dc);
            }

            dst += 4*s->linesize;
        }

        r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
    }else{
        q_ac = rv34_qscale_tab[s->qscale];

        for(j = 0; j < 4; j++){
            for(i = 0; i < 4; i++, cbp >>= 1){
                if(!(cbp & 1)) continue;

                rv34_process_block(r, dst + 4*i, s->linesize,
                                   r->luma_vlc, 0, q_ac, q_ac);
            }
            dst += 4*s->linesize;
        }
    }

    q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
    q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];

    for(j = 1; j < 3; j++){
        dst = s->dest[j];
        for(i = 0; i < 4; i++, cbp >>= 1){
            uint8_t *pdst;
            if(!(cbp & 1)) continue;
            pdst = dst + (i&1)*4 + (i&2)*2*s->uvlinesize;

            rv34_process_block(r, pdst, s->uvlinesize,
                               r->chroma_vlc, 1, q_dc, q_ac);
        }
    }

    return 0;
}

static int rv34_decode_intra_macroblock(RV34DecContext *r, int8_t *intra_types)
{
    MpegEncContext *s = &r->s;
    int cbp, dist;
    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;

    // Calculate which neighbours are available. Maybe it's worth optimizing too.
    memset(r->avail_cache, 0, sizeof(r->avail_cache));
    fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4);
    dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
    if(s->mb_x && dist)
        r->avail_cache[5] =
        r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
    if(dist >= s->mb_width)
        r->avail_cache[2] =
        r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
    if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
        r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
    if(s->mb_x && dist > s->mb_width)
        r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];

    s->qscale = r->si.quant;
    cbp = rv34_decode_intra_mb_header(r, intra_types);
    r->cbp_luma  [mb_pos] = cbp;
    r->cbp_chroma[mb_pos] = cbp >> 16;
    r->deblock_coefs[mb_pos] = 0xFFFF;
    s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;

    if(cbp == -1)
        return -1;

    if(r->is16){
        rv34_output_i16x16(r, intra_types, cbp);
        return 0;
    }

    rv34_output_intra(r, intra_types, cbp);
    return 0;
}

static int check_slice_end(RV34DecContext *r, MpegEncContext *s)
{
    int bits;
    if(s->mb_y >= s->mb_height)
        return 1;
    if(!s->mb_num_left)
        return 1;
    if(r->s.mb_skip_run > 1)
        return 0;
    bits = get_bits_left(&s->gb);
    if(bits <= 0 || (bits < 8 && !show_bits(&s->gb, bits)))
        return 1;
    return 0;
}


static void rv34_decoder_free(RV34DecContext *r)
{
    av_freep(&r->intra_types_hist);
    r->intra_types = NULL;
    av_freep(&r->tmp_b_block_base);
    av_freep(&r->mb_type);
    av_freep(&r->cbp_luma);
    av_freep(&r->cbp_chroma);
    av_freep(&r->deblock_coefs);
}


static int rv34_decoder_alloc(RV34DecContext *r)
{
    r->intra_types_stride = r->s.mb_width * 4 + 4;

    r->cbp_chroma       = av_malloc(r->s.mb_stride * r->s.mb_height *
                                    sizeof(*r->cbp_chroma));
    r->cbp_luma         = av_malloc(r->s.mb_stride * r->s.mb_height *
                                    sizeof(*r->cbp_luma));
    r->deblock_coefs    = av_malloc(r->s.mb_stride * r->s.mb_height *
                                    sizeof(*r->deblock_coefs));
    r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 *
                                    sizeof(*r->intra_types_hist));
    r->mb_type          = av_mallocz(r->s.mb_stride * r->s.mb_height *
                                     sizeof(*r->mb_type));

    if (!(r->cbp_chroma       && r->cbp_luma && r->deblock_coefs &&
          r->intra_types_hist && r->mb_type)) {
        rv34_decoder_free(r);
        return AVERROR(ENOMEM);
    }

    r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;

    return 0;
}


static int rv34_decoder_realloc(RV34DecContext *r)
{
    rv34_decoder_free(r);
    return rv34_decoder_alloc(r);
}


static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int buf_size)
{
    MpegEncContext *s = &r->s;
    GetBitContext *gb = &s->gb;
    int mb_pos, slice_type;
    int res;

    init_get_bits(&r->s.gb, buf, buf_size*8);
    res = r->parse_slice_header(r, gb, &r->si);
    if(res < 0){
        av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n");
        return -1;
    }

    slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
    if (slice_type != s->pict_type) {
        av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
        return AVERROR_INVALIDDATA;
    }
    if (s->width != r->si.width || s->height != r->si.height) {
        av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n");
        return AVERROR_INVALIDDATA;
    }

    r->si.end = end;
    s->qscale = r->si.quant;
    s->mb_num_left = r->si.end - r->si.start;
    r->s.mb_skip_run = 0;

    mb_pos = s->mb_x + s->mb_y * s->mb_width;
    if(r->si.start != mb_pos){
        av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->si.start, mb_pos);
        s->mb_x = r->si.start % s->mb_width;
        s->mb_y = r->si.start / s->mb_width;
    }
    memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
    s->first_slice_line = 1;
    s->resync_mb_x = s->mb_x;
    s->resync_mb_y = s->mb_y;

    ff_init_block_index(s);
    while(!check_slice_end(r, s)) {
        ff_update_block_index(s);

        if(r->si.type)
            res = rv34_decode_inter_macroblock(r, r->intra_types + s->mb_x * 4 + 4);
        else
            res = rv34_decode_intra_macroblock(r, r->intra_types + s->mb_x * 4 + 4);
        if(res < 0){
            ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_ERROR);
            return -1;
        }
        if (++s->mb_x == s->mb_width) {
            s->mb_x = 0;
            s->mb_y++;
            ff_init_block_index(s);

            memmove(r->intra_types_hist, r->intra_types, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));
            memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));

            if(r->loop_filter && s->mb_y >= 2)
                r->loop_filter(r, s->mb_y - 2);

            if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
                ff_thread_report_progress(&s->current_picture_ptr->tf,
                                          s->mb_y - 2, 0);

        }
        if(s->mb_x == s->resync_mb_x)
            s->first_slice_line=0;
        s->mb_num_left--;
    }
    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);

    return s->mb_y == s->mb_height;
}

/** @} */ // recons group end

/**
 * Initialize decoder.
 */
av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
{
    RV34DecContext *r = avctx->priv_data;
    MpegEncContext *s = &r->s;
    int ret;

    ff_MPV_decode_defaults(s);
    s->avctx      = avctx;
    s->out_format = FMT_H263;
    s->codec_id   = avctx->codec_id;

    s->width  = avctx->width;
    s->height = avctx->height;

    r->s.avctx = avctx;
    avctx->flags |= CODEC_FLAG_EMU_EDGE;
    r->s.flags |= CODEC_FLAG_EMU_EDGE;
    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
    avctx->has_b_frames = 1;
    s->low_delay = 0;

    if ((ret = ff_MPV_common_init(s)) < 0)
        return ret;

    ff_h264_pred_init(&r->h, AV_CODEC_ID_RV40, 8, 1);

#if CONFIG_RV30_DECODER
    if (avctx->codec_id == AV_CODEC_ID_RV30)
        ff_rv30dsp_init(&r->rdsp);
#endif
#if CONFIG_RV40_DECODER
    if (avctx->codec_id == AV_CODEC_ID_RV40)
        ff_rv40dsp_init(&r->rdsp);
#endif

    if ((ret = rv34_decoder_alloc(r)) < 0)
        return ret;

    if(!intra_vlcs[0].cbppattern[0].bits)
        rv34_init_tables();

    avctx->internal->allocate_progress = 1;

    return 0;
}

int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx)
{
    int err;
    RV34DecContext *r = avctx->priv_data;

    r->s.avctx = avctx;

    if (avctx->internal->is_copy) {
        r->tmp_b_block_base = NULL;
        if ((err = ff_MPV_common_init(&r->s)) < 0)
            return err;
        if ((err = rv34_decoder_alloc(r)) < 0)
            return err;
    }

    return 0;
}

int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
{
    RV34DecContext *r = dst->priv_data, *r1 = src->priv_data;
    MpegEncContext * const s = &r->s, * const s1 = &r1->s;
    int err;

    if (dst == src || !s1->context_initialized)
        return 0;

    if (s->height != s1->height || s->width != s1->width) {
        s->height = s1->height;
        s->width  = s1->width;
        if ((err = ff_MPV_common_frame_size_change(s)) < 0)
            return err;
        if ((err = rv34_decoder_realloc(r)) < 0)
            return err;
    }

    if ((err = ff_mpeg_update_thread_context(dst, src)))
        return err;

    r->cur_pts  = r1->cur_pts;
    r->last_pts = r1->last_pts;
    r->next_pts = r1->next_pts;

    memset(&r->si, 0, sizeof(r->si));

    return 0;
}

static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n)
{
    if(avctx->slice_count) return avctx->slice_offset[n];
    else                   return AV_RL32(buf + n*8 - 4) == 1 ? AV_RL32(buf + n*8) :  AV_RB32(buf + n*8);
}

static int finish_frame(AVCodecContext *avctx, AVFrame *pict)
{
    RV34DecContext *r = avctx->priv_data;
    MpegEncContext *s = &r->s;
    int got_picture = 0, ret;

    ff_er_frame_end(&s->er);
    ff_MPV_frame_end(s);
    s->mb_num_left = 0;

    if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
        ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);

    if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
        if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
            return ret;
        ff_print_debug_info(s, s->current_picture_ptr, pict);
        ff_mpv_export_qp_table(s, pict, s->current_picture_ptr, FF_QSCALE_TYPE_MPEG1);
        got_picture = 1;
    } else if (s->last_picture_ptr != NULL) {
        if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
            return ret;
        ff_print_debug_info(s, s->last_picture_ptr, pict);
        ff_mpv_export_qp_table(s, pict, s->last_picture_ptr, FF_QSCALE_TYPE_MPEG1);
        got_picture = 1;
    }

    return got_picture;
}

static AVRational update_sar(int old_w, int old_h, AVRational sar, int new_w, int new_h)
{
    // attempt to keep aspect during typical resolution switches
    if (!sar.num)
        sar = (AVRational){1, 1};

    sar = av_mul_q(sar, (AVRational){new_h * old_w, new_w * old_h});
    return sar;
}

int ff_rv34_decode_frame(AVCodecContext *avctx,
                            void *data, int *got_picture_ptr,
                            AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    RV34DecContext *r = avctx->priv_data;
    MpegEncContext *s = &r->s;
    AVFrame *pict = data;
    SliceInfo si;
    int i, ret;
    int slice_count;
    const uint8_t *slices_hdr = NULL;
    int last = 0;

    /* no supplementary picture */
    if (buf_size == 0) {
        /* special case for last picture */
        if (s->low_delay==0 && s->next_picture_ptr) {
            if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0)
                return ret;
            s->next_picture_ptr = NULL;

            *got_picture_ptr = 1;
        }
        return 0;
    }

    if(!avctx->slice_count){
        slice_count = (*buf++) + 1;
        slices_hdr = buf + 4;
        buf += 8 * slice_count;
        buf_size -= 1 + 8 * slice_count;
    }else
        slice_count = avctx->slice_count;

    //parse first slice header to check whether this frame can be decoded
    if(get_slice_offset(avctx, slices_hdr, 0) < 0 ||
       get_slice_offset(avctx, slices_hdr, 0) > buf_size){
        av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
        return AVERROR_INVALIDDATA;
    }
    init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), (buf_size-get_slice_offset(avctx, slices_hdr, 0))*8);
    if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){
        av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");
        return AVERROR_INVALIDDATA;
    }
    if ((!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) &&
        si.type == AV_PICTURE_TYPE_B) {
        av_log(avctx, AV_LOG_ERROR, "Invalid decoder state: B-frame without "
               "reference data.\n");
        return AVERROR_INVALIDDATA;
    }
    if(   (avctx->skip_frame >= AVDISCARD_NONREF && si.type==AV_PICTURE_TYPE_B)
       || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=AV_PICTURE_TYPE_I)
       ||  avctx->skip_frame >= AVDISCARD_ALL)
        return avpkt->size;

    /* first slice */
    if (si.start == 0) {
        if (s->mb_num_left > 0) {
            av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.\n",
                   s->mb_num_left);
            ff_er_frame_end(&s->er);
            ff_MPV_frame_end(s);
        }

        if (s->width != si.width || s->height != si.height) {
            int err;

            av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n",
                   si.width, si.height);

            if (av_image_check_size(si.width, si.height, 0, s->avctx))
                return AVERROR_INVALIDDATA;

            s->avctx->sample_aspect_ratio = update_sar(
                s->width, s->height, s->avctx->sample_aspect_ratio,
                si.width, si.height);
            s->width  = si.width;
            s->height = si.height;
            avcodec_set_dimensions(s->avctx, s->width, s->height);
            if ((err = ff_MPV_common_frame_size_change(s)) < 0)
                return err;
            if ((err = rv34_decoder_realloc(r)) < 0)
                return err;
        }
        s->pict_type = si.type ? si.type : AV_PICTURE_TYPE_I;
        if (ff_MPV_frame_start(s, s->avctx) < 0)
            return -1;
        ff_mpeg_er_frame_start(s);
        if (!r->tmp_b_block_base) {
            int i;

            r->tmp_b_block_base = av_malloc(s->linesize * 48);
            for (i = 0; i < 2; i++)
                r->tmp_b_block_y[i] = r->tmp_b_block_base
                                      + i * 16 * s->linesize;
            for (i = 0; i < 4; i++)
                r->tmp_b_block_uv[i] = r->tmp_b_block_base + 32 * s->linesize
                                       + (i >> 1) * 8 * s->uvlinesize
                                       + (i &  1) * 16;
        }
        r->cur_pts = si.pts;
        if (s->pict_type != AV_PICTURE_TYPE_B) {
            r->last_pts = r->next_pts;
            r->next_pts = r->cur_pts;
        } else {
            int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
            int dist0   = GET_PTS_DIFF(r->cur_pts,  r->last_pts);
            int dist1   = GET_PTS_DIFF(r->next_pts, r->cur_pts);

            if(!refdist){
                r->mv_weight1 = r->mv_weight2 = r->weight1 = r->weight2 = 8192;
                r->scaled_weight = 0;
            }else{
                r->mv_weight1 = (dist0 << 14) / refdist;
                r->mv_weight2 = (dist1 << 14) / refdist;
                if((r->mv_weight1|r->mv_weight2) & 511){
                    r->weight1 = r->mv_weight1;
                    r->weight2 = r->mv_weight2;
                    r->scaled_weight = 0;
                }else{
                    r->weight1 = r->mv_weight1 >> 9;
                    r->weight2 = r->mv_weight2 >> 9;
                    r->scaled_weight = 1;
                }
            }
        }
        s->mb_x = s->mb_y = 0;
        ff_thread_finish_setup(s->avctx);
    } else if (HAVE_THREADS &&
               (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
        av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames in frame "
               "multithreading mode (start MB is %d).\n", si.start);
        return AVERROR_INVALIDDATA;
    }

    for(i = 0; i < slice_count; i++){
        int offset = get_slice_offset(avctx, slices_hdr, i);
        int size;
        if(i+1 == slice_count)
            size = buf_size - offset;
        else
            size = get_slice_offset(avctx, slices_hdr, i+1) - offset;

        if(offset < 0 || offset > buf_size){
            av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
            break;
        }

        r->si.end = s->mb_width * s->mb_height;
        s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;

        if(i+1 < slice_count){
            if (get_slice_offset(avctx, slices_hdr, i+1) < 0 ||
                get_slice_offset(avctx, slices_hdr, i+1) > buf_size) {
                av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
                break;
            }
            init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8);
            if(r->parse_slice_header(r, &r->s.gb, &si) < 0){
                if(i+2 < slice_count)
                    size = get_slice_offset(avctx, slices_hdr, i+2) - offset;
                else
                    size = buf_size - offset;
            }else
                r->si.end = si.start;
        }
        if (size < 0 || size > buf_size - offset) {
            av_log(avctx, AV_LOG_ERROR, "Slice size is invalid\n");
            break;
        }
        last = rv34_decode_slice(r, r->si.end, buf + offset, size);
        if(last)
            break;
    }

    if (s->current_picture_ptr) {
        if (last) {
            if(r->loop_filter)
                r->loop_filter(r, s->mb_height - 1);

            ret = finish_frame(avctx, pict);
            if (ret < 0)
                return ret;
            *got_picture_ptr = ret;
        } else if (HAVE_THREADS &&
                   (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
            av_log(avctx, AV_LOG_INFO, "marking unfished frame as finished\n");
            /* always mark the current frame as finished, frame-mt supports
             * only complete frames */
            ff_er_frame_end(&s->er);
            ff_MPV_frame_end(s);
            s->mb_num_left = 0;
            ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
            return AVERROR_INVALIDDATA;
        }
    }

    return avpkt->size;
}

av_cold int ff_rv34_decode_end(AVCodecContext *avctx)
{
    RV34DecContext *r = avctx->priv_data;

    ff_MPV_common_end(&r->s);
    rv34_decoder_free(r);

    return 0;
}
