]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/rv34.c
md5: cosmetics
[ffmpeg] / libavcodec / rv34.c
index 66036414d547cc44753f9734b8bfc147dead3b6e..c5dcfdcba45afc63720e2d4844d7dd76b4fc39ce 100644 (file)
@@ -2,25 +2,25 @@
  * RV30/40 decoder common data
  * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
  *
- * This file is part of FFmpeg.
+ * This file is part of Libav.
  *
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav 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,
+ * Libav 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
+ * License along with Libav; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
- * @file libavcodec/rv34.c
+ * @file
  * RV30/40 decoder common data
  */
 
 
 //#define DEBUG
 
+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,
@@ -56,24 +62,51 @@ static const int rv34_mb_type_to_lavc[12] = {
 
 static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];
 
+static int rv34_decode_mv(RV34DecContext *r, int block_type);
+
 /**
- * @defgroup vlc RV30/40 VLC generating functions
+ * @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)
+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[size], syms[size];
-    uint8_t bits2[size];
+    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++){
@@ -92,10 +125,12 @@ static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t
     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];
     init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize,
                     bits2, 1, 1,
                     cw,    2, 2,
-                    syms,  2, 2, INIT_VLC_USE_STATIC);
+                    syms,  2, 2, INIT_VLC_USE_NEW_STATIC);
 }
 
 /**
@@ -107,27 +142,30 @@ static av_cold void rv34_init_tables(void)
 
     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);
-            rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j], NULL);
-            rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j],  NULL);
-            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);
+            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);
         }
-        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);
-        rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL);
+        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);
-        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);
+        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);
-            rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j], NULL);
-            rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j],  NULL);
+            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);
+        rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL, i*12 + 106);
     }
 }
 
@@ -135,7 +173,7 @@ static av_cold void rv34_init_tables(void)
 
 
 /**
- * @defgroup transform RV30/40 inverse transform functions
+ * @name RV30/40 inverse transform functions
  * @{
  */
 
@@ -210,7 +248,7 @@ static void rv34_inv_transform_noround(DCTELEM *block){
 
 
 /**
- * @defgroup block RV30/40 4x4 block decoding functions
+ * @name RV30/40 4x4 block decoding functions
  * @{
  */
 
@@ -357,7 +395,7 @@ static inline void rv34_dequant4x4_16x16(DCTELEM *block, int Qdc, int Q)
 
 
 /**
- * @defgroup bitstream RV30/40 bitstream parsing
+ * @name RV30/40 bitstream parsing
  * @{
  */
 
@@ -396,10 +434,76 @@ static inline int rv34_decode_dquant(GetBitContext *gb, int quant)
         return get_bits(gb, 5);
 }
 
+/**
+ * Decode macroblock header and return CBP in case of success, -1 otherwise.
+ */
+static int rv34_decode_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;
+
+    if(!r->si.type){
+        r->is16 = get_bits1(gb);
+        if(!r->is16 && !r->rv30){
+            if(!get_bits1(gb))
+                av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
+        }
+        s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA;
+        r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA;
+    }else{
+        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
 
 /**
- * @defgroup mv motion vector related code (prediction, reconstruction, motion compensation)
+ * @name motion vector related code (prediction, reconstruction, motion compensation)
  * @{
  */
 
@@ -410,7 +514,7 @@ static const uint8_t part_sizes_w[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 2,
 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] = { 5, 6, 9, 10 };
+static const uint8_t avail_indexes[4] = { 6, 7, 10, 11 };
 
 /**
  * motion vector prediction
@@ -523,21 +627,21 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
     memset(A, 0, sizeof(A));
     memset(B, 0, sizeof(B));
     memset(C, 0, sizeof(C));
-    if((r->avail_cache[5-1] & type) & mask){
+    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[5-4] & type) & mask){
+    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[5-4] && (r->avail_cache[5-2] & type) & mask){
+    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[5-5] & type) & mask){
+    }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;
@@ -554,8 +658,9 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
             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)
-        fill_rectangle(cur_pic->motion_val[!dir][mv_pos], 2, 2, s->b8_stride, 0, 4);
+    if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){
+        ZERO8x2(cur_pic->motion_val[!dir][mv_pos], s->b8_stride);
+    }
 }
 
 /**
@@ -681,12 +786,12 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
         uint8_t *uvbuf= s->edge_emu_buffer + 22 * s->linesize;
 
         srcY -= 2 + 2*s->linesize;
-        ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6,
+        s->dsp.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;
-        ff_emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1,
+        s->dsp.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);
-        ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1,
+        s->dsp.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;
@@ -776,11 +881,11 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type)
     switch(block_type){
     case RV34_MB_TYPE_INTRA:
     case RV34_MB_TYPE_INTRA16x16:
-        fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4);
+        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 == FF_P_TYPE){
-            fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4);
+        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;
         }
@@ -788,8 +893,8 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type)
         //surprisingly, it uses motion scheme from next reference frame
         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)){
-            fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4);
-            fill_rectangle(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4);
+            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++)
@@ -800,7 +905,7 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type)
             rv34_mc_2mv(r, block_type);
         else
             rv34_mc_2mv_skip(r);
-        fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4);
+        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:
@@ -848,7 +953,7 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type)
 /** @} */ // mv group
 
 /**
- * @defgroup recons Macroblock reconstruction functions
+ * @name Macroblock reconstruction functions
  * @{
  */
 /** mapping of RV30/40 intra prediction types to standard H.264 types */
@@ -928,17 +1033,17 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c
     int idx;
 
     // Set neighbour information.
-    if(r->avail_cache[0])
-        avail[0] = 1;
     if(r->avail_cache[1])
-        avail[1] = avail[2] = 1;
+        avail[0] = 1;
     if(r->avail_cache[2])
-        avail[3] = avail[4] = 1;
+        avail[1] = avail[2] = 1;
     if(r->avail_cache[3])
-        avail[5] = 1;
+        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[8])
+    if(r->avail_cache[9])
         avail[24] = avail[32] = 1;
 
     Y = s->dest[0];
@@ -954,15 +1059,15 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c
                     rv34_add_4x4_block(Y, s->linesize, s->block[(i>>1)+(j&2)], (i&1)*4+(j&1)*32);
             }
             Y += s->linesize * 4 - 4*4;
-            intra_types += s->b4_stride;
+            intra_types += r->intra_types_stride;
         }
-        intra_types -= s->b4_stride * 4;
-        fill_rectangle(r->avail_cache + 5, 2, 2, 4, 0, 4);
+        intra_types -= r->intra_types_stride * 4;
+        fill_rectangle(r->avail_cache + 6, 2, 2, 4, 0, 4);
         for(j = 0; j < 2; j++){
-            idx = 5 + j*4;
+            idx = 6 + j*4;
             for(i = 0; i < 2; i++, cbp >>= 1, idx++){
-                rv34_pred_4x4_block(r, U + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*s->b4_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]);
-                rv34_pred_4x4_block(r, V + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*s->b4_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]);
+                rv34_pred_4x4_block(r, U + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*r->intra_types_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]);
+                rv34_pred_4x4_block(r, V + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*r->intra_types_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]);
                 r->avail_cache[idx] = 1;
                 if(cbp & 0x01)
                     rv34_add_4x4_block(U + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[4], i*4+j*32);
@@ -972,7 +1077,7 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c
         }
     }else{
         itype = ittrans16[intra_types[0]];
-        itype = adjust_pred16(itype, r->avail_cache[5-4], r->avail_cache[5-1]);
+        itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
         r->h.pred16x16[itype](Y, s->linesize);
         dsp->add_pixels_clamped(s->block[0], Y,     s->linesize);
         dsp->add_pixels_clamped(s->block[1], Y + 8, s->linesize);
@@ -982,7 +1087,7 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c
 
         itype = ittrans16[intra_types[0]];
         if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
-        itype = adjust_pred16(itype, r->avail_cache[5-4], r->avail_cache[5-1]);
+        itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
         r->h.pred8x8[itype](U, s->uvlinesize);
         dsp->add_pixels_clamped(s->block[4], U, s->uvlinesize);
         r->h.pred8x8[itype](V, s->uvlinesize);
@@ -990,79 +1095,6 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c
     }
 }
 
-/** @} */ // recons group
-
-/**
- * @addtogroup bitstream
- * Decode macroblock header and return CBP in case of success, -1 otherwise.
- */
-static int rv34_decode_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;
-
-    if(!r->si.type){
-        r->is16 = get_bits1(gb);
-        if(!r->is16 && !r->rv30){
-            if(!get_bits1(gb))
-                av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
-        }
-        s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA;
-        r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA;
-    }else{
-        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 == FF_P_TYPE)
-                r->mb_type[mb_pos] = RV34_MB_P_16x16;
-            if(s->pict_type == FF_B_TYPE)
-                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, s->b4_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, s->b4_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) * s->b4_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);
-}
-
-/**
- * @addtogroup recons
- * @{
- */
 /**
  * mask for retrieving all bits in coded block pattern
  * corresponding to one 8x8 block
@@ -1072,6 +1104,8 @@ static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types)
 #define U_CBP_MASK 0x0F0000
 #define V_CBP_MASK 0xF00000
 
+/** @} */ // recons group
+
 
 static void rv34_apply_differences(RV34DecContext *r, int cbp)
 {
@@ -1105,7 +1139,7 @@ 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];
+    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))
@@ -1143,24 +1177,24 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
 
     // 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 + 5, 2, 2, 4, 1, 4);
+    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[4] =
-        r->avail_cache[8] = s->current_picture_ptr->mb_type[mb_pos - 1];
+        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[1] =
-        r->avail_cache[2] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
+        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[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 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[0] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];
+        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_mb_header(r, intra_types);
     r->cbp_luma  [mb_pos] = cbp;
     r->cbp_chroma[mb_pos] = cbp >> 16;
-    if(s->pict_type == FF_I_TYPE)
+    if(s->pict_type == AV_PICTURE_TYPE_I)
         r->deblock_coefs[mb_pos] = 0xFFFF;
     else
         r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos];
@@ -1250,21 +1284,23 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
             MPV_common_end(s);
             s->width  = r->si.width;
             s->height = r->si.height;
+            avcodec_set_dimensions(s->avctx, s->width, s->height);
             if(MPV_common_init(s) < 0)
                 return -1;
-            r->intra_types_hist = av_realloc(r->intra_types_hist, s->b4_stride * 4 * 2 * sizeof(*r->intra_types_hist));
-            r->intra_types = r->intra_types_hist + s->b4_stride * 4;
+            r->intra_types_stride = s->mb_width*4 + 4;
+            r->intra_types_hist = av_realloc(r->intra_types_hist, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
+            r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;
             r->mb_type = av_realloc(r->mb_type, r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type));
             r->cbp_luma   = av_realloc(r->cbp_luma,   r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma));
             r->cbp_chroma = av_realloc(r->cbp_chroma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma));
             r->deblock_coefs = av_realloc(r->deblock_coefs, r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs));
         }
-        s->pict_type = r->si.type ? r->si.type : FF_I_TYPE;
+        s->pict_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
         if(MPV_frame_start(s, s->avctx) < 0)
             return -1;
         ff_er_frame_start(s);
         r->cur_pts = r->si.pts;
-        if(s->pict_type != FF_B_TYPE){
+        if(s->pict_type != AV_PICTURE_TYPE_B){
             r->last_pts = r->next_pts;
             r->next_pts = r->cur_pts;
         }
@@ -1283,7 +1319,7 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
         s->mb_x = r->si.start % s->mb_width;
         s->mb_y = r->si.start / s->mb_width;
     }
-    memset(r->intra_types_hist, -1, s->b4_stride * 4 * 2 * sizeof(*r->intra_types_hist));
+    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;
@@ -1293,7 +1329,7 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
         ff_update_block_index(s);
         s->dsp.clear_blocks(s->block[0]);
 
-        if(rv34_decode_macroblock(r, r->intra_types + s->mb_x * 4 + 1) < 0){
+        if(rv34_decode_macroblock(r, r->intra_types + s->mb_x * 4 + 4) < 0){
             ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_ERROR|DC_ERROR|MV_ERROR);
             return -1;
         }
@@ -1302,8 +1338,8 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
             s->mb_y++;
             ff_init_block_index(s);
 
-            memmove(r->intra_types_hist, r->intra_types, s->b4_stride * 4 * sizeof(*r->intra_types_hist));
-            memset(r->intra_types, -1, s->b4_stride * 4 * sizeof(*r->intra_types_hist));
+            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);
@@ -1345,10 +1381,11 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
     if (MPV_common_init(s) < 0)
         return -1;
 
-    ff_h264_pred_init(&r->h, CODEC_ID_RV40);
+    ff_h264_pred_init(&r->h, CODEC_ID_RV40, 8);
 
-    r->intra_types_hist = av_malloc(s->b4_stride * 4 * 2 * sizeof(*r->intra_types_hist));
-    r->intra_types = r->intra_types_hist + s->b4_stride * 4;
+    r->intra_types_stride = 4*s->mb_stride + 4;
+    r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
+    r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;
 
     r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type));
 
@@ -1370,8 +1407,10 @@ static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n)
 
 int ff_rv34_decode_frame(AVCodecContext *avctx,
                             void *data, int *data_size,
-                            const uint8_t *buf, int buf_size)
+                            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;
@@ -1410,17 +1449,12 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");
         return -1;
     }
-    if((!s->last_picture_ptr || !s->last_picture_ptr->data[0]) && si.type == FF_B_TYPE)
+    if((!s->last_picture_ptr || !s->last_picture_ptr->data[0]) && si.type == AV_PICTURE_TYPE_B)
         return -1;
-    /* skip b frames if we are in a hurry */
-    if(avctx->hurry_up && si.type==FF_B_TYPE) return buf_size;
-    if(   (avctx->skip_frame >= AVDISCARD_NONREF && si.type==FF_B_TYPE)
-       || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=FF_I_TYPE)
+    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 buf_size;
-    /* skip everything if we are in a hurry>=5 */
-    if(avctx->hurry_up>=5)
-        return buf_size;
 
     for(i=0; i<slice_count; i++){
         int offset= get_slice_offset(avctx, slices_hdr, i);
@@ -1457,7 +1491,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
             r->loop_filter(r, s->mb_height - 1);
         ff_er_frame_end(s);
         MPV_frame_end(s);
-        if (s->pict_type == FF_B_TYPE || s->low_delay) {
+        if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
             *pict= *(AVFrame*)s->current_picture_ptr;
         } else if (s->last_picture_ptr != NULL) {
             *pict= *(AVFrame*)s->last_picture_ptr;