[FFmpeg-soc] [soc]: r1378 - in rv40: rv30.c rv34.c rv34.h rv34data.h rv34vlc.h rv40.c rv40data.h rv40vlc.h
kostya
subversion at mplayerhq.hu
Wed Sep 19 18:55:06 CEST 2007
Author: kostya
Date: Wed Sep 19 18:55:05 2007
New Revision: 1378
Log:
Finally split rv30 and rv40 decoders
Added:
rv40/rv30.c
- copied, changed from r1377, /rv40/rv40.c
rv40/rv34.c
- copied, changed from r1377, /rv40/rv40.c
rv40/rv34.h
- copied, changed from r1377, /rv40/rv40.c
rv40/rv34data.h
- copied, changed from r1371, /rv40/rv40data.h
rv40/rv34vlc.h
- copied unchanged from r1373, /rv40/rv40vlc.h
Removed:
rv40/rv40vlc.h
Modified:
rv40/rv40.c
rv40/rv40data.h
Copied: rv40/rv30.c (from r1377, /rv40/rv40.c)
==============================================================================
--- /rv40/rv40.c (original)
+++ rv40/rv30.c Wed Sep 19 18:55:05 2007
@@ -1,6 +1,6 @@
/*
- * RV40 decoder
- * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
+ * RV30 decoder
+ * Copyright (c) 2007 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
@@ -20,534 +20,23 @@
*/
/**
- * @file rv40.c
- * RV30 and RV40 decoder.
+ * @file rv30.c
+ * RV30 decoder.
*/
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
-#include "rv40vlc.h"
-#include "rv40vlc2.h"
-#include "rv40data.h"
+#include "rv34.h"
#include "rv30data.h"
-#include "h264pred.h"
-
-//#define DEBUG
-
-/** Translation of RV40 macroblock types to lavc ones */
-static const int rv34_mb_type_to_lavc[12] = {
- MB_TYPE_INTRA, MB_TYPE_INTRA16x16, MB_TYPE_16x16, MB_TYPE_8x8,
- MB_TYPE_16x16, MB_TYPE_16x16, MB_TYPE_SKIP, MB_TYPE_DIRECT2,
- MB_TYPE_16x8, MB_TYPE_8x16, MB_TYPE_DIRECT2, MB_TYPE_16x16
-};
-
-/**
- * RV30 and RV40 Macroblock types
- * @{
- */
-enum RV40BlockTypes{
- RV34_MB_TYPE_INTRA, ///< Intra macroblock
- RV34_MB_TYPE_INTRA16x16, ///< Intra macroblock with DCs in a separate 4x4 block
- RV34_MB_P_16x16, ///< P-frame macroblock, one motion frame
- RV34_MB_P_8x8, ///< P-frame macroblock, 8x8 motion compensation partitions
- RV34_MB_B_FORWARD, ///< B-frame macroblock, forward prediction
- RV34_MB_B_BACKWARD, ///< B-frame macroblock, backward prediction
- RV34_MB_SKIP, ///< Skipped block
- RV34_MB_B_INTERP, ///< Bidirectionally predicted B-frame macroblock, no motion vectors
- RV34_MB_P_16x8, ///< P-frame macroblock, 16x8 motion compensation partitions
- RV34_MB_P_8x16, ///< P-frame macroblock, 8x16 motion compensation partitions
- RV34_MB_B_DIRECT, ///< Bidirectionally predicted B-frame macroblock, two motion vectors
- RV34_MB_P_MIX16x16, ///< P-frame macroblock with DCs in a separate 4x4 block, one motion vector
- RV34_MB_TYPES
-};
-/** @} */
-
-/**
- * VLC tables used by decoder
- *
- * intra frame VLC sets do not contain some of those tables
- */
-typedef struct RV34VLC{
- VLC cbppattern[2]; ///< VLCs used for pattern of coded block patterns decoding
- VLC cbp[2][4]; ///< VLCs used for coded block patterns decoding
- VLC first_pattern[4]; ///< VLCs used for decoding coefficients in the first subblock
- VLC second_pattern[2]; ///< VLCs used for decoding coefficients in the subblocks 2 and 3
- VLC third_pattern[2]; ///< VLCs used for decoding coefficients in the last subblock
- VLC coefficient; ///< VLCs used for decoding big coefficients
-}RV34VLC;
-
-/** Essential slice information */
-typedef struct SliceInfo{
- int type; ///< slice type (intra, inter)
- int size; ///< size of the slice in bits
- int quant; ///< quantizer used for this slice
- int vlc_set; ///< VLCs used for this slice
- int start, end; ///< start and end macroblocks of the slice
- int header_size; ///< header size in bits
- int width; ///< coded width
- int height; ///< coded height
-}SliceInfo;
-
-/** Slice information saved for truncated slices */
-typedef struct SavedSliceInfo{
- uint8_t *data; ///< bitstream data
- int data_size; ///< data size
- int bits_used; ///< bits used up to last decoded block
- int mb_x, mb_y; ///< coordinates of the last decoded block
-}SavedSliceInfo;
-
-/** Decoder context */
-typedef struct RV34DecContext{
- MpegEncContext s;
- int mb_bits; ///< bits needed to read MB offet in slice header
- int *intra_types_hist; ///< old block types, used for prediction
- int *intra_types; ///< block types
- int intra_types_stride; ///< stride for block types data
- int block_start; ///< start of slice in blocks
- uint8_t *luma_dc_quant_i;///< luma subblock DC quantizer for intraframes
- uint8_t *luma_dc_quant_p;///< luma subblock DC quantizer for interframes
-
- int vlc_set; ///< index of currently selected VLC set
- RV34VLC *cur_vlcs; ///< VLC set used for current frame decoding
- int bits; ///< slice size in bits
- H264PredContext h; ///< functions for 4x4 and 16x16 intra block prediction
- SliceInfo si; ///< current slice information
- SliceInfo prev_si; ///< info for the saved slice
- uint8_t *slice_data; ///< saved slice data
-
- int *mb_type; ///< internal macroblock types
- int block_type; ///< current block type
- int luma_vlc; ///< which VLC set will be used for luma blocks decoding
- int chroma_vlc; ///< which VLC set will be used for chroma blocks decoding
- int is16; ///< current block has additional 16x16 specific features or not
- int dmv[4][2]; ///< differential motion vectors for the current macroblock
-
- int truncated; ///< flag signalling that slice ended prematurely
- SavedSliceInfo ssi; ///< data for truncated slice
-
- int rv30; ///< indicates which RV variasnt is currently decoded
- int rpr; ///< one field size in RV30 slice header
-
- int avail[4]; ///< whether left, top, top rights and top left MBs are available
-
- int (*parse_slice_header)(struct RV34DecContext *r, GetBitContext *gb, SliceInfo *si);
- int (*decode_intra_types)(struct RV34DecContext *r, GetBitContext *gb, int *dst);
- int (*decode_mb_info)(struct RV34DecContext *r);
-}RV34DecContext;
-
-static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];
-static VLC omega_part_vlc;
-static VLC aic_top_vlc;
-static VLC aic_mode1_vlc[AIC_MODE1_NUM], aic_mode2_vlc[AIC_MODE2_NUM];
-static VLC ptype_vlc[NUM_PTYPE_VLCS], btype_vlc[NUM_BTYPE_VLCS];
-
-/**
- * @defgroup vlc RV40 VLC generating functions
- * @{
- */
-
-/**
- * Generate VLC from codeword lengths
- */
-static int rv34_gen_vlc(const uint8_t *bits2, int size, VLC *vlc)
-{
- int i;
- int counts[17] = {0}, codes[17];
- uint16_t cw[size], syms[size];
- uint8_t bits[size];
- int maxbits = 0, realsize;
- int ret;
-
- realsize = 0;
- for(i = 0; i < size; i++){
- if(bits2[i]){
- bits[realsize] = bits2[i];
- syms[realsize] = i;
- realsize++;
- maxbits = FFMAX(maxbits, bits2[i]);
- counts[bits2[i]]++;
- }
- }
-
- size = realsize;
- 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[bits[i]]++;
-
- ret = init_vlc_sparse(vlc, FFMIN(maxbits, 9), size,
- bits, 1, 1,
- cw, 2, 2,
- syms, 2, 2, INIT_VLC_USE_STATIC);
- return ret;
-}
-
-/**
- * Initialize all tables
- */
-static void rv34_init_tables()
-{
- int i, j, k;
-
- for(i = 0; i < NUM_INTRA_TABLES; i++){
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_intra_cbppatvlc_pointers[i][j], CBPPAT_VLC_SIZE, &intra_vlcs[i].cbppattern[j]);
- for(j = 0; j < 2; j++)
- for(k = 0; k < 4; k++)
- rv34_gen_vlc(rv34_intra_cbpvlc_pointers[i][j][k], CBP_VLC_SIZE, &intra_vlcs[i].cbp[j][k]);
- for(j = 0; j < 4; j++)
- rv34_gen_vlc(rv34_intra_firstpatvlc_pointers[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_intra_secondpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_intra_thirdpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j]);
- rv34_gen_vlc(rv34_intra_coeffvlc_pointers[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient);
- }
-
- for(i = 0; i < NUM_INTER_TABLES; i++){
- rv34_gen_vlc(rv34_inter_cbppatvlc_pointers[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0]);
- for(j = 0; j < 4; j++)
- rv34_gen_vlc(rv34_inter_cbpvlc_pointers[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_inter_firstpatvlc_pointers[i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_inter_secondpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_inter_thirdpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j]);
- rv34_gen_vlc(rv34_inter_coeffvlc_pointers[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient);
- }
-
- init_vlc(&aic_top_vlc, AIC_TOP_BITS, AIC_TOP_SIZE,
- rv40_aic_top_vlc_bits, 1, 1,
- rv40_aic_top_vlc_codes, 1, 1, INIT_VLC_USE_STATIC);
- for(i = 0; i < AIC_MODE1_NUM; i++){
- // For some reason every tenth VLC table is empty
- // So skip it for consistency
- // XXX: redo without this hack
- if((i % 10) == 9) continue;
- init_vlc(&aic_mode1_vlc[i], AIC_MODE1_BITS, AIC_MODE1_SIZE,
- aic_mode1_vlc_bits[i], 1, 1,
- aic_mode1_vlc_codes[i], 1, 1, INIT_VLC_USE_STATIC);
- }
- for(i = 0; i < AIC_MODE2_NUM; i++){
- init_vlc(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE,
- aic_mode2_vlc_bits[i], 1, 1,
- aic_mode2_vlc_codes[i], 2, 2, INIT_VLC_USE_STATIC);
- }
- init_vlc_sparse(&omega_part_vlc, OMEGA_BITS, NUM_OMEGA,
- omega_part_vlc_bits, 1, 1,
- omega_part_vlc_codes, 1, 1,
- omega_part_vlc_syms, 1, 1, INIT_VLC_USE_STATIC);
- for(i = 0; i < NUM_PTYPE_VLCS; i++)
- init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE,
- ptype_vlc_bits[i], 1, 1,
- ptype_vlc_codes[i], 1, 1,
- ptype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC);
- for(i = 0; i < NUM_BTYPE_VLCS; i++)
- init_vlc_sparse(&btype_vlc[i], BTYPE_VLC_BITS, BTYPE_VLC_SIZE,
- btype_vlc_bits[i], 1, 1,
- btype_vlc_codes[i], 1, 1,
- btype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC);
-}
-
-/** @} */ // vlc group
-
-
-/**
- * @defgroup transform RV40 inverse transform functions
- * @{
- */
-
-/**
- * Real Video 4.0 inverse transform
- * Code is almost the same as in SVQ3, only scaling is different
- */
-static void rv34_intra_inv_transform(DCTELEM *block, const int offset){
- int temp[16];
- unsigned int i;
-
- for(i=0; i<4; i++){
- const int z0= 13*(block[offset+i+8*0] + block[offset+i+8*2]);
- const int z1= 13*(block[offset+i+8*0] - block[offset+i+8*2]);
- const int z2= 7* block[offset+i+8*1] - 17*block[offset+i+8*3];
- const int z3= 17* block[offset+i+8*1] + 7*block[offset+i+8*3];
-
- temp[4*i+0]= z0+z3;
- temp[4*i+1]= z1+z2;
- temp[4*i+2]= z1-z2;
- temp[4*i+3]= z0-z3;
- }
-
- for(i=0; i<4; i++){
- const int z0= 13*(temp[4*0+i] + temp[4*2+i]) + 0x200;
- const int z1= 13*(temp[4*0+i] - temp[4*2+i]) + 0x200;
- const int z2= 7* temp[4*1+i] - 17*temp[4*3+i];
- const int z3= 17* temp[4*1+i] + 7*temp[4*3+i];
-
- block[offset+i*8+0]= (z0 + z3)>>10;
- block[offset+i*8+1]= (z1 + z2)>>10;
- block[offset+i*8+2]= (z1 - z2)>>10;
- block[offset+i*8+3]= (z0 - z3)>>10;
- }
-
-}
-
-/**
- * RealVideo 4.0 inverse transform - special version
- *
- * Code is almost the same but final coefficients are multiplied by 1.5
- * and have no rounding
- */
-static void rv34_intra_inv_transform_noround(DCTELEM *block, const int offset){
- int temp[16];
- unsigned int i;
-
- for(i=0; i<4; i++){
- const int z0= 13*(block[offset+i+8*0] + block[offset+i+8*2]);
- const int z1= 13*(block[offset+i+8*0] - block[offset+i+8*2]);
- const int z2= 7* block[offset+i+8*1] - 17*block[offset+i+8*3];
- const int z3= 17* block[offset+i+8*1] + 7*block[offset+i+8*3];
-
- temp[4*i+0]= z0+z3;
- temp[4*i+1]= z1+z2;
- temp[4*i+2]= z1-z2;
- temp[4*i+3]= z0-z3;
- }
-
- for(i=0; i<4; i++){
- const int z0= 13*(temp[4*0+i] + temp[4*2+i]);
- const int z1= 13*(temp[4*0+i] - temp[4*2+i]);
- const int z2= 7* temp[4*1+i] - 17*temp[4*3+i];
- const int z3= 17* temp[4*1+i] + 7*temp[4*3+i];
-
- block[offset+i*8+0]= ((z0 + z3)*3)>>11;
- block[offset+i*8+1]= ((z1 + z2)*3)>>11;
- block[offset+i*8+2]= ((z1 - z2)*3)>>11;
- block[offset+i*8+3]= ((z0 - z3)*3)>>11;
- }
-
-}
-
-/** @} */ // transform
-
-
-/**
- * @defgroup block RV40 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 table2;
- static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000};
- static const int shifts[4] = { 0, 2, 8, 10 };
- int *curshift = shifts;
- int i, t, mask;
-
- code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2);
- pattern = code & 0xF;
- code >>= 4;
-
- table2 = rv34_count_ones[pattern];
-
- for(mask = 8; mask; mask >>= 1, curshift++){
- if(!(pattern & mask)) continue;
- t = get_vlc2(gb, vlc->cbp[table][table2].table, vlc->cbp[table][table2].bits, 1);
- cbp |= rv34_cbp_code[t] << curshift[0];
- }
-
- for(i = 0; i < 4; i++){
- t = modulo_three_table[code][i];
- 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 bistream and store it
- */
-static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc)
-{
- 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;
- }
-}
-
-/**
- * Decode 2x2 subblock of coefficients
- */
-static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc)
-{
- int coeffs[4];
-
- coeffs[0] = modulo_three_table[code][0];
- coeffs[1] = modulo_three_table[code][1];
- coeffs[2] = modulo_three_table[code][2];
- coeffs[3] = modulo_three_table[code][3];
- decode_coeff(dst , coeffs[0], 3, gb, vlc);
- if(!is_block2){
- decode_coeff(dst+1, coeffs[1], 2, gb, vlc);
- decode_coeff(dst+8, coeffs[2], 2, gb, vlc);
- }else{
- decode_coeff(dst+8, coeffs[1], 2, gb, vlc);
- decode_coeff(dst+1, coeffs[2], 2, gb, vlc);
- }
- decode_coeff(dst+9, coeffs[3], 2, gb, vlc);
-}
-
-/**
- * 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 inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc)
-{
- int code, pattern;
-
- code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2);
-
- pattern = code & 0x7;
-
- code >>= 3;
- decode_subblock(dst, code, 0, gb, &rvlc->coefficient);
-
- if(pattern & 4){
- code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
- decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient);
- }
- 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 + 8*2, code, 1, gb, &rvlc->coefficient);
- }
- if(pattern & 1){
- code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
- decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient);
- }
-}
-
-/**
- * Dequantize ordinary 4x4 block
- * @todo optimize
- */
-static inline void rv34_dequant4x4(DCTELEM *block, int offset, int Qdc, int Q)
-{
- int i, j;
-
- block += offset;
- block[0] = (block[0] * Qdc + 8) >> 4;
- for(i = 0; i < 4; i++)
- for(j = !i; j < 4; j++)
- block[j + i*8] = (block[j + i*8] * Q + 8) >> 4;
-}
-
-/**
- * Dequantize 4x4 block of DC values for 16x16 macroblock
- * @todo optimize
- */
-static inline void rv34_dequant4x4_16x16(DCTELEM *block, int offset, int Qdc, int Q)
-{
- int i;
-
- block += offset;
- for(i = 0; i < 3; i++)
- block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Qdc + 8) >> 4;
- for(; i < 16; i++)
- block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Q + 8) >> 4;
-}
-/** @} */ //block functions
-
-
-/**
- * @defgroup bitstream RV40 bitstream parsing
- * @{
- */
-
-static inline int decode210(GetBitContext *gb){
- if (get_bits1(gb))
- return 0;
- else
- return 2 - get_bits1(gb);
-}
-
-/**
- * Get stored dimension from bitstream
- *
- * If the width/height is the standard one then it's coded as 3-bit index.
- * Otherwise it is coded as escaped 8-bit portions.
- */
-static int get_dimension(GetBitContext *gb, const int *dim1, const int *dim2)
-{
- int val, t;
-
- t = get_bits(gb, 3);
- val = dim1[t];
- if(!val && dim2)
- val = dim2[(t*2 | get_bits1(gb)) & 3];
- if(!val){
- do{
- t = get_bits(gb, 8);
- val += t << 2;
- }while(t == 0xFF);
- }
- return val;
-}
-
-/**
- * Get encoded picture size - usually this is called from rv40_parse_slice_header
- */
-static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h)
-{
- *w = get_dimension(gb, rv40_standard_widths, NULL);
- *h = get_dimension(gb, rv40_standard_heights, rv40_standard_heights2);
-}
-
-/**
- * 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){
- if(quant < 19) quant += 10;
- else if(quant < 26) quant += 5;
- }
- if(mod == 1)
- if(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)]];
-}
static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
{
int t, mb_bits;
int w = r->s.width, h = r->s.height;
- int i, mb_size;
+ int mb_size;
memset(si, 0, sizeof(SliceInfo));
get_bits(gb, 3);
@@ -563,87 +52,13 @@ static int rv30_parse_slice_header(RV34D
si->width = w;
si->height = h;
mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
- for(i = 0; i < 5; i++)
- if(rv34_mb_max_sizes[i] > mb_size)
- break;
- mb_bits = rv34_mb_bits_sizes[i];
+ mb_bits = ff_rv34_get_start_offset(gb, mb_size);
si->start = get_bits(gb, mb_bits);
get_bits1(gb);
si->header_size = get_bits_count(gb);
return 0;
}
-static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
-{
- int t, mb_bits;
- int w = r->s.width, h = r->s.height;
- int i, mb_size;
-
- memset(si, 0, sizeof(SliceInfo));
- si->type = -1;
- if(get_bits1(gb))
- return -1;
- si->type = get_bits(gb, 2);
- if(si->type == 1) si->type = 0;
- si->quant = get_bits(gb, 5);
- if(get_bits(gb, 2))
- return -1;
- si->vlc_set = get_bits(gb, 2);
- get_bits1(gb);
- t = get_bits(gb, 13); /// ???
- if(!si->type || !get_bits1(gb))
- rv40_parse_picture_size(gb, &w, &h);
- si->width = w;
- si->height = h;
- mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
- for(i = 0; i < 5; i++)
- if(rv34_mb_max_sizes[i] > mb_size)
- break;
- mb_bits = rv34_mb_bits_sizes[i];
- si->start = get_bits(gb, mb_bits);
- si->header_size = get_bits_count(gb);
-
- return 0;
-}
-
-/**
- * Decode variable-length code constructed from variable-length codes
- * similar to Even-Rodeh and Elias Omega codes
- *
- * Code is constructed from bit chunks of even length (odd length means end of code)
- * and chunks are coded with variable-length codes too
- */
-int ff_rv34_get_omega(GetBitContext *gb)
-{
- int code = 1, t, tb;
-
- for(;;){
- t = get_vlc2(gb, omega_part_vlc.table, OMEGA_BITS, 1);
- tb = t >> 5;
- code = (code << tb) | (t & 0xF);
- if(t & 0x10) break;
- }
- return code;
-}
-
-/**
- * Decode signed integer variable-length code constructed from variable-length codes
- * similar to Even-Rodeh and Elias Omega codes
- *
- * Code is constructed from bit chunks of even length (odd length means end of code)
- * and chunks are coded with variable-length codes too
- */
-int ff_rv34_get_omega_signed(GetBitContext *gb)
-{
- int code;
-
- code = ff_rv34_get_omega(gb);
- if(code & 1)
- return -(code >> 1);
- else
- return code >> 1;
-}
-
/**
* Decode 4x4 intra types array
*/
@@ -677,80 +92,6 @@ static int rv30_decode_intra_types(RV34D
}
/**
- * Decode 4x4 intra types array
- */
-static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int *dst)
-{
- MpegEncContext *s = &r->s;
- int i, j, k, v;
- int A, B, C;
- int pattern;
- int *ptr;
-
- for(i = 0; i < 4; i++, dst += r->intra_types_stride){
- if(!i && s->first_slice_line){
- pattern = get_vlc2(gb, aic_top_vlc.table, AIC_TOP_BITS, 1);
- dst[0] = (pattern >> 2) & 2;
- dst[1] = (pattern >> 1) & 2;
- dst[2] = pattern & 2;
- dst[3] = (pattern << 1) & 2;
- continue;
- }
- ptr = dst;
- for(j = 0; j < 4; j++){
- /* Coefficients are read using VLC chosen by prediction pattern
- * First one (used for retrieving a pair of coefficients) is
- * constructed from top, top right and left coefficients
- * Second one (used for retrieving only one coefficient) is
- * top + 10 * left
- */
- A = ptr[-r->intra_types_stride + 1]; // it won't be used for the last coefficient in a row
- B = ptr[-r->intra_types_stride];
- C = ptr[-1];
- pattern = A + (B << 4) + (C << 8);
- for(k = 0; k < MODE2_PATTERNS_NUM; k++)
- if(pattern == rv40_aic_table_index[k])
- break;
- if(j < 3 && k < MODE2_PATTERNS_NUM){ //pattern is found, decoding 2 coefficients
- v = get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2);
- *ptr++ = v/9;
- *ptr++ = v%9;
- j++;
- }else{
- if(B != -1 && C != -1)
- v = get_vlc2(gb, aic_mode1_vlc[B + C*10].table, AIC_MODE1_BITS, 1);
- else{ // tricky decoding
- v = 0;
- switch(C){
- case -1: // code 0 -> 1, 1 -> 0
- if(B == -1 || B == 0 || B == 1)
- v = get_bits1(gb) ^ 1;
- break;
- case 0:
- case 2: // code 0 -> 2, 1 -> 0
- v = (get_bits1(gb) ^ 1) << 1;
- break;
- }
- }
- *ptr++ = v;
- }
- }
- }
- return 0;
-}
-
-/**
- * Decode quantizer difference and return modified quantizer
- */
-static inline int rv34_decode_dquant(GetBitContext *gb, int quant)
-{
- if(get_bits1(gb))
- return av_clip(quant + rv34_dquant_tab[quant * 2 + get_bits1(gb)], 0, 31);
- else
- return get_bits(gb, 5);
-}
-
-/**
* Decode macroblock information
*/
static int rv30_decode_mb_info(RV34DecContext *r)
@@ -776,1375 +117,28 @@ static int rv30_decode_mb_info(RV34DecCo
return rv30_b_types[code];
}
-/**
- * Decode macroblock information
- */
-static int rv40_decode_mb_info(RV34DecContext *r)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int q, i;
- int prev_type = 0;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int blocks[RV34_MB_TYPES];
- int count = 0;
-
- if(!r->s.mb_skip_run)
- r->s.mb_skip_run = ff_rv34_get_omega(gb);
-
- if(--r->s.mb_skip_run)
- return RV34_MB_SKIP;
-
- memset(blocks, 0, sizeof(blocks));
- if(r->avail[0])
- blocks[r->mb_type[mb_pos - 1]]++;
- if(r->avail[1])
- blocks[r->mb_type[mb_pos - s->mb_stride]]++;
- if(r->avail[1] && r->avail[2])
- blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++;
- if(r->avail[1] && r->avail[3])
- blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++;
-
- for(i = 0; i < RV34_MB_TYPES; i++){
- if(blocks[i] > count){
- count = blocks[i];
- prev_type = i;
- }
- }
- if(s->pict_type == P_TYPE){
- if(prev_type == RV34_MB_SKIP) prev_type = RV34_MB_P_16x16;
- prev_type = block_num_to_ptype_vlc_num[prev_type];
- q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1);
- if(q < PBTYPE_ESCAPE)
- return q;
- q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1);
- av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n");
- }else{
- prev_type = block_num_to_btype_vlc_num[prev_type];
- q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1);
- if(q < PBTYPE_ESCAPE)
- return q;
- q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1);
- av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n");
- }
- return 0;
-}
-
-/** @} */ //bitstream functions
-
-/**
- * @defgroup mv 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 };
-
-/**
- * Motion vectors prediction
- *
- * Motion prediction performed for the block by using median prediction of
- * motion vector from the left, top and right top blocks but in corener cases
- * some other vectors may be used instead
- */
-static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no)
-{
- MpegEncContext *s = &r->s;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
- int A[2], B[2], C[2];
- int no_A = 1, no_B = 1, no_C = 1;
- int i, j;
- int mx, my;
-
- memset(A, 0, sizeof(A));
- memset(B, 0, sizeof(B));
- memset(C, 0, sizeof(C));
- no_A = !r->avail[0];
- no_B = !r->avail[1];
- no_C = !r->avail[2];
- switch(block_type){
- case RV34_MB_P_16x16:
- case RV34_MB_P_MIX16x16:
- if(!no_C){
- 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];
- }
- break;
- case RV34_MB_P_8x8:
- mv_pos += (subblock_no & 1) + (subblock_no >> 1)*s->b8_stride;
- if(subblock_no & 1) no_A = 0;
- if(subblock_no & 2) no_B = 0;
- no_C |= (subblock_no == 3);
- if(subblock_no == 2) no_C = 0;
- if(!subblock_no) no_C = no_B;
- if(!no_C){
- 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];
- }
- if(subblock_no == 3){
- no_C = 0;
- 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];
- }
- break;
- case RV34_MB_P_16x8:
- mv_pos += subblock_no*s->b8_stride;
- no_B &= ~subblock_no;
- no_C |= subblock_no;
- if(!no_C){
- 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];
- }
- break;
- case RV34_MB_P_8x16:
- mv_pos += subblock_no;
- no_A &= ~subblock_no;
- if(!subblock_no) no_C = no_B;
- if(!no_C){
- 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];
- }
- break;
- default:
- no_A = no_B = no_C = 1;
- }
- if(!no_A){
- 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(!no_B){
- 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(no_C){
- if(no_B || (no_A && !r->rv30)){
- C[0] = A[0];
- C[1] = A[1];
- }else{
- 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];
- }
- }
- mx = mid_pred(A[0], B[0], C[0]);
- my = mid_pred(A[1], B[1], C[1]);
- mx += r->dmv[subblock_no][0];
- my += r->dmv[subblock_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;
- }
- }
-}
-
-/**
- * Predict motion vector for B-frame macroblock.
- */
-static inline void rv34_pred_b_vector(int A[2], int B[2], int C[2], int no_A, int no_B, int no_C, int *mx, int *my)
-{
- if(no_A + no_B + no_C){
- *mx = A[0] + B[0] + C[0];
- *my = A[1] + B[1] + C[1];
- if(no_A + no_B + no_C == 1){
- *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)
-{
- 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][2], B[2][2], C[2][2];
- int no_A[2], no_B[2], no_C[2];
- int c_mv_pos;
- int mx[2], my[2];
- int i, j;
-
- memset(A, 0, sizeof(A));
- memset(B, 0, sizeof(B));
- memset(C, 0, sizeof(C));
- memset(mx, 0, sizeof(mx));
- memset(my, 0, sizeof(my));
- if(!r->avail[0])
- no_A[0] = no_A[1] = 1;
- else{
- no_A[0] = no_A[1] = 0;
- if(r->mb_type[mb_pos - 1] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - 1] != RV34_MB_B_DIRECT)
- no_A[0] = 1;
- if(r->mb_type[mb_pos - 1] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - 1] != RV34_MB_B_DIRECT)
- no_A[1] = 1;
- if(!no_A[0]){
- A[0][0] = s->current_picture_ptr->motion_val[0][mv_pos - 1][0];
- A[0][1] = s->current_picture_ptr->motion_val[0][mv_pos - 1][1];
- }
- if(!no_A[1]){
- A[1][0] = s->current_picture_ptr->motion_val[1][mv_pos - 1][0];
- A[1][1] = s->current_picture_ptr->motion_val[1][mv_pos - 1][1];
- }
- }
- if(!r->avail[1]){
- no_B[0] = no_B[1] = 1;
- }else{
- no_B[0] = no_B[1] = 0;
- if(r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_DIRECT)
- no_B[0] = 1;
- if(r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_DIRECT)
- no_B[1] = 1;
- if(!no_B[0]){
- B[0][0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][0];
- B[0][1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][1];
- }
- if(!no_B[1]){
- B[1][0] = s->current_picture_ptr->motion_val[1][mv_pos - s->b8_stride][0];
- B[1][1] = s->current_picture_ptr->motion_val[1][mv_pos - s->b8_stride][1];
- }
- }
- if(r->avail[2]){
- no_C[0] = no_C[1] = 0;
- if(r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_DIRECT)
- no_C[0] = 1;
- if(r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_DIRECT)
- no_C[1] = 1;
- c_mv_pos = mv_pos - s->b8_stride + 2;
- }else if(r->avail[3]){
- no_C[0] = no_C[1] = 0;
- if(r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_DIRECT)
- no_C[0] = 1;
- if(r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_DIRECT)
- no_C[1] = 1;
- c_mv_pos = mv_pos - s->b8_stride - 1;
- }else{
- no_C[0] = no_C[1] = 1;
- c_mv_pos = 0;
- }
- if(!no_C[0]){
- C[0][0] = s->current_picture_ptr->motion_val[0][c_mv_pos][0];
- C[0][1] = s->current_picture_ptr->motion_val[0][c_mv_pos][1];
- }
- if(!no_C[1]){
- C[1][0] = s->current_picture_ptr->motion_val[1][c_mv_pos][0];
- C[1][1] = s->current_picture_ptr->motion_val[1][c_mv_pos][1];
- }
- switch(block_type){
- case RV34_MB_B_FORWARD:
- rv34_pred_b_vector(A[0], B[0], C[0], no_A[0], no_B[0], no_C[0], &mx[0], &my[0]);
- r->dmv[1][0] = 0;
- r->dmv[1][1] = 0;
- break;
- case RV34_MB_B_BACKWARD:
- r->dmv[1][0] = r->dmv[0][0];
- r->dmv[1][1] = r->dmv[0][1];
- r->dmv[0][0] = 0;
- r->dmv[0][1] = 0;
- rv34_pred_b_vector(A[1], B[1], C[1], no_A[1], no_B[1], no_C[1], &mx[1], &my[1]);
- break;
- case RV34_MB_B_DIRECT:
- rv34_pred_b_vector(A[0], B[0], C[0], no_A[0], no_B[0], no_C[0], &mx[0], &my[0]);
- rv34_pred_b_vector(A[1], B[1], C[1], no_A[1], no_B[1], no_C[1], &mx[1], &my[1]);
- break;
- default:
- no_A[0] = no_A[1] = no_B[0] = no_B[1] = no_C[0] = no_C[1] = 1;
- }
-
- mx[0] += r->dmv[0][0];
- my[0] += r->dmv[0][1];
- mx[1] += r->dmv[1][0];
- my[1] += r->dmv[1][1];
- for(j = 0; j < 2; j++){
- for(i = 0; i < 2; i++){
- s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx[0];
- s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my[0];
- s->current_picture_ptr->motion_val[1][mv_pos + i + j*s->b8_stride][0] = mx[1];
- s->current_picture_ptr->motion_val[1][mv_pos + i + j*s->b8_stride][1] = my[1];
- }
- }
-}
-
-/**
- * Generic motion compensation function - hopefully compiler will optimize it for each case
- *
- * @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
- */
-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)
-{
- MpegEncContext *s = &r->s;
- uint8_t *Y, *U, *V, *srcY, *srcU, *srcV;
- int dxy, mx, my, 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;
-
- mx = s->current_picture_ptr->motion_val[0][mv_pos][0];
- my = s->current_picture_ptr->motion_val[0][mv_pos][1];
- srcY = s->last_picture_ptr->data[0];
- srcU = s->last_picture_ptr->data[1];
- srcV = s->last_picture_ptr->data[2];
- src_x = s->mb_x * 16 + xoff + (mx >> 2);
- src_y = s->mb_y * 16 + yoff + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (xoff >> 1) + (mx >> 3);
- uvsrc_y = s->mb_y * 8 + (yoff >> 1) + (my >> 3);
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
- if( (unsigned)(src_x - !!(mx&3)*2) > s->h_edge_pos - !!(mx&3)*2 - (width <<3) - 3
- || (unsigned)(src_y - !!(my&3)*2) > s->v_edge_pos - !!(my&3)*2 - (height<<3) - 3){
- uint8_t *uvbuf= s->edge_emu_buffer + 20 * s->linesize;
-
- srcY -= 2 + 2*s->linesize;
- ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+4, (height<<3)+4,
- 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,
- 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,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- srcU = uvbuf;
- srcV = uvbuf + 16;
- }
- dxy = ((my & 3) << 2) | (mx & 3);
- uvmx = mx & 6;
- uvmy = my & 6;
- 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;
- if(block_type == RV34_MB_P_16x8){
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- Y += 8;
- srcY += 8;
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[0] (U, srcU, s->uvlinesize, 4, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[0] (V, srcV, s->uvlinesize, 4, uvmx, uvmy);
- }else if(block_type == RV34_MB_P_8x16){
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- Y += 8 * s->linesize;
- srcY += 8 * s->linesize;
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[1] (U, srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[1] (V, srcV, s->uvlinesize, 8, uvmx, uvmy);
- }else if(block_type == RV34_MB_P_8x8){
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[1] (U, srcU, s->uvlinesize, 4, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[1] (V, srcV, s->uvlinesize, 4, uvmx, uvmy);
- }else{
- s->dsp.put_h264_qpel_pixels_tab[0][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[0] (U, srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[0] (V, srcV, s->uvlinesize, 8, uvmx, uvmy);
- }
-}
-
-/**
- * B-frame specific motion compensation function
- *
- * @param r decoder context
- * @param block_type type of the current block
- */
-static inline void rv34_mc_b(RV34DecContext *r, const int block_type)
-{
- MpegEncContext *s = &r->s;
- uint8_t *srcY, *srcU, *srcV;
- int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
-
- if(block_type != RV34_MB_B_BACKWARD){
- mx = s->current_picture_ptr->motion_val[0][mv_pos][0];
- my = s->current_picture_ptr->motion_val[0][mv_pos][1];
- srcY = s->last_picture_ptr->data[0];
- srcU = s->last_picture_ptr->data[1];
- srcV = s->last_picture_ptr->data[2];
- }else{
- mx = s->current_picture_ptr->motion_val[1][mv_pos][0];
- my = s->current_picture_ptr->motion_val[1][mv_pos][1];
- srcY = s->next_picture_ptr->data[0];
- srcU = s->next_picture_ptr->data[1];
- srcV = s->next_picture_ptr->data[2];
- }
- if(block_type == RV34_MB_B_INTERP){
- mx += (s->next_picture_ptr->motion_val[0][mv_pos][0] + 1) >> 1;
- my += (s->next_picture_ptr->motion_val[0][mv_pos][1] + 1) >> 1;
- }
- src_x = s->mb_x * 16 + (mx >> 2);
- src_y = s->mb_y * 16 + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (mx >> 3);
- uvsrc_y = s->mb_y * 8 + (my >> 3);
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
- if( (unsigned)(src_x - !!(mx&3)*2) > s->h_edge_pos - !!(mx&3)*2 - 16 - 3
- || (unsigned)(src_y - !!(my&3)*2) > s->v_edge_pos - !!(my&3)*2 - 16 - 3){
- uint8_t *uvbuf= s->edge_emu_buffer + 20 * s->linesize;
-
- srcY -= 2 + 2*s->linesize;
- ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 16+4, 16+4,
- 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, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- srcU = uvbuf;
- srcV = uvbuf + 16;
- }
- dxy = ((my & 3) << 2) | (mx & 3);
- uvmx = mx & 6;
- uvmy = my & 6;
- s->dsp.put_h264_qpel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[0] (s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[0] (s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
-}
-
-/**
- * B-frame specific motion compensation function - for direct/interpolated blocks
- *
- * @param r decoder context
- * @param block_type type of the current block
- */
-static inline void rv34_mc_b_interp(RV34DecContext *r, const int block_type)
-{
- MpegEncContext *s = &r->s;
- uint8_t *srcY, *srcU, *srcV;
- int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
-
- mx = s->current_picture_ptr->motion_val[1][mv_pos][0];
- my = s->current_picture_ptr->motion_val[1][mv_pos][1];
- if(block_type == RV34_MB_B_INTERP){
- mx -= s->next_picture_ptr->motion_val[0][mv_pos][0] >> 1;
- my -= s->next_picture_ptr->motion_val[0][mv_pos][1] >> 1;
- }
- srcY = s->next_picture_ptr->data[0];
- srcU = s->next_picture_ptr->data[1];
- srcV = s->next_picture_ptr->data[2];
-
- src_x = s->mb_x * 16 + (mx >> 2);
- src_y = s->mb_y * 16 + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (mx >> 3);
- uvsrc_y = s->mb_y * 8 + (my >> 3);
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
- if( (unsigned)(src_x - !!(mx&3)*2) > s->h_edge_pos - !!(mx&3)*2 - 16 - 3
- || (unsigned)(src_y - !!(my&3)*2) > s->v_edge_pos - !!(my&3)*2 - 16 - 3){
- uint8_t *uvbuf= s->edge_emu_buffer + 20 * s->linesize;
-
- srcY -= 2 + 2*s->linesize;
- ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 16+4, 16+4,
- 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, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- srcU = uvbuf;
- srcV = uvbuf + 16;
- }
- dxy = ((my & 3) << 2) | (mx & 3);
- uvmx = mx & 6;
- uvmy = my & 6;
- s->dsp.avg_h264_qpel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize);
- s->dsp.avg_h264_chroma_pixels_tab[0] (s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.avg_h264_chroma_pixels_tab[0] (s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
-}
-
-/**
- * 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;
-
- switch(block_type){
- case RV34_MB_TYPE_INTRA:
- case RV34_MB_TYPE_INTRA16x16:
- for(j = 0; j < 2; j++){
- for(i = 0; i < 2; i++){
- s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + i + j*s->b8_stride][0] = 0;
- s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + i + j*s->b8_stride][1] = 0;
- }
- }
- return 0;
- case RV34_MB_SKIP:
- r->dmv[0][0] = 0;
- r->dmv[0][1] = 0;
- if(s->pict_type == P_TYPE){
- rv34_pred_mv(r, block_type, 0);
- rv34_mc(r, block_type, 0, 0, 0, 2, 2);
- break;
- }
- case RV34_MB_B_INTERP:
- r->dmv[0][0] = 0;
- r->dmv[0][1] = 0;
- r->dmv[1][0] = 0;
- r->dmv[1][1] = 0;
- rv34_pred_mv_b (r, RV34_MB_B_INTERP);
- rv34_mc_b (r, RV34_MB_B_INTERP);
- rv34_mc_b_interp(r, RV34_MB_B_INTERP);
- break;
- case RV34_MB_P_16x16:
- case RV34_MB_P_MIX16x16:
- r->dmv[0][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[0][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv(r, block_type, 0);
- rv34_mc(r, block_type, 0, 0, 0, 2, 2);
- break;
- case RV34_MB_B_FORWARD:
- case RV34_MB_B_BACKWARD:
- r->dmv[0][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[0][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv_b (r, block_type);
- rv34_mc_b (r, block_type);
- break;
- case RV34_MB_P_16x8:
- case RV34_MB_P_8x16:
- case RV34_MB_B_DIRECT:
- r->dmv[0][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[0][1] = ff_rv34_get_omega_signed(gb);
- r->dmv[1][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[1][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv(r, block_type, 0);
- rv34_pred_mv(r, block_type, 1);
- if(block_type == RV34_MB_P_16x8){
- rv34_mc(r, block_type, 0, 0, 0, 2, 1);
- rv34_mc(r, block_type, 0, 8, s->b8_stride, 2, 1);
- }
- if(block_type == RV34_MB_P_8x16){
- rv34_mc(r, block_type, 0, 0, 0, 1, 2);
- rv34_mc(r, block_type, 8, 0, 1, 1, 2);
- }
- if(block_type == RV34_MB_B_DIRECT){
- rv34_pred_mv_b (r, block_type);
- rv34_mc_b (r, block_type);
- rv34_mc_b_interp(r, block_type);
- }
- break;
- case RV34_MB_P_8x8:
- for(i=0;i< 4;i++){
- r->dmv[i][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[i][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv(r, block_type, i);
- rv34_mc(r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1);
- }
- break;
- }
-
- return 0;
-}
-/** @} */ // mv group
-
-/**
- * @defgroup recons Macroblock reconstruction functions
- * @{
- */
-/** Mapping of RV40 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 RV40 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 no_up, int no_left, int no_down, int no_right)
-{
- uint8_t *prev = dst - stride + 4;
- uint32_t topleft;
-
- if(no_up && no_left)
- itype = DC_128_PRED;
- else if(no_up){
- if(itype == VERT_PRED) itype = HOR_PRED;
- if(itype == DC_PRED) itype = LEFT_DC_PRED;
- }else if(no_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(no_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(no_right && !no_up){
- topleft = dst[-stride + 3] * 0x01010101;
- prev = &topleft;
- }
- r->h.pred4x4[itype](dst, prev, stride);
-}
-
-/** add_pixels_clamped for 4x4 block */
-static void rv34_add_4x4_block(uint8_t *dst, int stride, DCTELEM block[64], int off)
-{
- int x, y;
- for(y = 0; y < 4; y++)
- for(x = 0; x < 4; x++)
- dst[x + y*stride] = av_clip_uint8(dst[x + y*stride] + block[off + x+y*8]);
-}
-
-static void rv34_output_macroblock(RV34DecContext *r, int *intra_types, int cbp, int is16)
-{
- MpegEncContext *s = &r->s;
- DSPContext *dsp = &s->dsp;
- int i, j;
- uint8_t *Y, *YY, *U, *V;
- int no_up, no_left, no_topright, itype;
-
- no_up = !r->avail[1];
- Y = s->dest[0];
- U = s->dest[1];
- V = s->dest[2];
- if(!is16){
- for(j = 0; j < 4; j++){
- no_left = !r->avail[0];
- YY = Y;
- for(i = 0; i < 4; i++, cbp >>= 1, YY += 4){
- no_topright = no_up || (i==3 && j) || (i==3 && !j && (s->mb_x-1) == s->mb_width);
- rv34_pred_4x4_block(r, YY, s->linesize, ittrans[intra_types[i]], no_up, no_left, i || (j==3), no_topright);
- no_left = 0;
- if(!(cbp & 1)) continue;
- rv34_add_4x4_block(YY, s->linesize, s->block[(i>>1)+(j&2)], (i&1)*4+(j&1)*32);
- }
- no_up = 0;
- Y += s->linesize * 4;
- intra_types += r->intra_types_stride;
- }
- intra_types -= r->intra_types_stride * 4;
- no_up = !r->avail[1];
- for(j = 0; j < 2; j++){
- no_left = !r->avail[0];
- for(i = 0; i < 2; i++, cbp >>= 1, no_left = 0){
- no_topright = no_up || (i && j) || (i && !j && (s->mb_x-1) == s->mb_width);
- 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]], no_up, no_left, i || j, no_topright);
- 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]], no_up, no_left, i || j, no_topright);
- if(cbp & 0x01)
- rv34_add_4x4_block(U + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[4], i*4+j*32);
- if(cbp & 0x10)
- rv34_add_4x4_block(V + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[5], i*4+j*32);
- }
- no_up = 0;
- }
- }else{
- no_left = !r->avail[0];
- itype = ittrans16[intra_types[0]];
- if(no_up && no_left)
- itype = DC_128_PRED8x8;
- else if(no_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(no_left){
- if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8;
- if(itype == HOR_PRED8x8) itype = VERT_PRED8x8;
- if(itype == DC_PRED8x8) itype = TOP_DC_PRED8x8;
- }
- r->h.pred16x16[itype](Y, s->linesize);
- dsp->add_pixels_clamped(s->block[0], Y, s->current_picture.linesize[0]);
- dsp->add_pixels_clamped(s->block[1], Y + 8, s->current_picture.linesize[0]);
- Y += s->current_picture.linesize[0] * 8;
- dsp->add_pixels_clamped(s->block[2], Y, s->current_picture.linesize[0]);
- dsp->add_pixels_clamped(s->block[3], Y + 8, s->current_picture.linesize[0]);
-
- itype = ittrans16[intra_types[0]];
- if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
- if(no_up && no_left)
- itype = DC_128_PRED8x8;
- else if(no_up){
- if(itype == VERT_PRED8x8) itype = HOR_PRED8x8;
- if(itype == DC_PRED8x8) itype = LEFT_DC_PRED8x8;
- }else if(no_left){
- if(itype == HOR_PRED8x8) itype = VERT_PRED8x8;
- if(itype == DC_PRED8x8) itype = TOP_DC_PRED8x8;
- }
- r->h.pred8x8[itype](U, s->uvlinesize);
- dsp->add_pixels_clamped(s->block[4], U, s->uvlinesize);
- r->h.pred8x8[itype](V, s->uvlinesize);
- dsp->add_pixels_clamped(s->block[5], V, s->uvlinesize);
- }
-}
-
-/** @} */ // recons group
-
-/**
- * @addtogroup bitstream
- * Decode macroblock header and return CBP in case of success, -1 otherwise.
- */
-static int rv34_decode_mb_header(RV34DecContext *r, int *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->rv30){
- r->is16 = 0;
- switch(decode210(gb)){
- case 0: // 16x16 block
- r->is16 = 1;
- break;
- case 1:
- break;
- case 2:
- av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
- // q = decode_dquant(gb);
- break;
- }
- 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 if(!r->si.type && r->rv30){
- r->is16 = get_bits1(gb);
- 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 == P_TYPE)
- r->mb_type[mb_pos] = RV34_MB_P_16x16;
- if(s->pict_type == B_TYPE)
- r->mb_type[mb_pos] = RV34_MB_B_INTERP;
- }
- 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){
- for(i = 0; i < 16; i++)
- intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 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){
- if(r->decode_intra_types(r, gb, intra_types) < 0)
- return -1;
- r->chroma_vlc = 0;
- r->luma_vlc = 1;
- }else{
- t = get_bits(gb, 2);
- for(i = 0; i < 16; i++)
- intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = t;
- r->chroma_vlc = 0;
- r->luma_vlc = 2;
- }
- 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);
-}
-
-/**
- * @addtogroup recons
- * @{
- */
-/** Mask for retrieving all bits in coded block pattern
- * corresponding to one 8x8 block.
- */
-#define LUMA_CBP_BLOCK_MASK 0x303
-
-#define U_CBP_MASK 0x0F0000
-#define V_CBP_MASK 0xF00000
-
-
-static void rv34_apply_differences(RV34DecContext *r, int cbp)
-{
- static const int shifts[4] = { 0, 2, 8, 10 };
- MpegEncContext *s = &r->s;
- int i;
-
- for(i = 0; i < 4; i++)
- if(cbp & (LUMA_CBP_BLOCK_MASK << shifts[i]))
- s->dsp.add_pixels_clamped(s->block[i], s->dest[0] + (i & 1)*8 + (i&2)*4*s->linesize, s->linesize);
- if(cbp & U_CBP_MASK)
- s->dsp.add_pixels_clamped(s->block[4], s->dest[1], s->uvlinesize);
- if(cbp & V_CBP_MASK)
- s->dsp.add_pixels_clamped(s->block[5], s->dest[2], s->uvlinesize);
-}
-
-static int rv34_decode_macroblock(RV34DecContext *r, int *intra_types)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int cbp, cbp2;
- int i, blknum, blkoff;
- DCTELEM block16[64];
- int luma_dc_quant;
-
- // calculate which neighbours are available
- memset(r->avail, 0, sizeof(r->avail));
- if(s->mb_x && !(s->first_slice_line && s->mb_x == s->resync_mb_x))
- r->avail[0] = 1;
- if(!s->first_slice_line)
- r->avail[1] = 1;
- if((s->mb_x+1) < s->mb_width && (!s->first_slice_line || (s->first_slice_line && (s->mb_x+1) == s->resync_mb_x)))
- r->avail[2] = 1;
- if(s->mb_x && !s->first_slice_line && !((s->mb_y-1)==s->resync_mb_y && s->mb_x == s->resync_mb_x))
- r->avail[3] = 1;
-
- s->qscale = r->si.quant;
- cbp = cbp2 = rv34_decode_mb_header(r, intra_types);
-
- if(cbp == -1)
- return -1;
-
- luma_dc_quant = r->si.type ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale];
- if(r->is16){
- memset(block16, 0, sizeof(block16));
- rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0);
- rv34_dequant4x4_16x16(block16, 0, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
- rv34_intra_inv_transform_noround(block16, 0);
- }
-
- for(i = 0; i < 16; i++, cbp >>= 1){
- if(!r->is16 && !(cbp & 1)) continue;
- blknum = ((i & 2) >> 1) + ((i & 8) >> 2);
- blkoff = ((i & 1) << 2) + ((i & 4) << 3);
- if(cbp & 1)
- rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0);
- if((cbp & 1) || r->is16){
- rv34_dequant4x4(s->block[blknum], blkoff, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
- if(r->is16) //FIXME: optimize
- s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)];
- rv34_intra_inv_transform(s->block[blknum], blkoff);
- }
- }
- if(r->block_type == RV34_MB_P_MIX16x16)
- r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
- for(; i < 24; i++, cbp >>= 1){
- if(!(cbp & 1)) continue;
- blknum = ((i & 4) >> 2) + 4;
- blkoff = ((i & 1) << 2) + ((i & 2) << 4);
- rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1);
- rv34_dequant4x4(s->block[blknum], blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]);
- rv34_intra_inv_transform(s->block[blknum], blkoff);
- }
- if(IS_INTRA(s->current_picture_ptr->mb_type[s->mb_x + s->mb_y*s->mb_stride]))
- rv34_output_macroblock(r, intra_types, cbp2, r->is16);
- else
- rv34_apply_differences(r, cbp2);
-
- return 0;
-}
-
-static int check_slice_end(RV34DecContext *r, MpegEncContext *s)
-{
- int bits;
- if(r->s.mb_skip_run > 1)
- return 0;
- if(s->mb_y >= s->mb_height)
- return 1;
- bits = r->bits - get_bits_count(&s->gb);
- if(bits < 0 || (bits < 8 && !show_bits(&s->gb, bits)))
- return 1;
- return 0;
-}
-
-static inline int slice_compare(SliceInfo *si1, SliceInfo *si2)
-{
- return si1->type != si2->type ||
- si1->start >= si2->start ||
- si1->width != si2->width ||
- si1->height != si2->height;
-}
-
-static int rv34_decode_slice(RV34DecContext *r, int size, int end, int *last)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int mb_pos;
- int res;
- int old_mb_x = r->ssi.mb_x, old_mb_y = r->ssi.mb_y;
- *last = 1;
-
- init_get_bits(&r->s.gb, r->slice_data, r->si.size);
- res = r->parse_slice_header(r, gb, &r->si);
- if((res < 0 && !s->current_picture_ptr) || (r->prev_si.type == -1 && r->si.start)){
- av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n");
- *last = 0;
- return -1;
- }
- if(res < 0 || (r->prev_si.type != -1 && slice_compare(&r->prev_si, &r->si))){
- r->ssi.data = av_realloc(r->ssi.data, r->ssi.data_size + (size>>3));
- memcpy(r->ssi.data + r->ssi.data_size, r->slice_data, size >> 3);
- r->ssi.data_size += size >> 3; // XXX: overflow check?
- size = r->ssi.data_size * 8;
- init_get_bits(&r->s.gb, r->ssi.data, r->ssi.data_size * 8);
- r->si = r->prev_si;
- skip_bits(gb, r->ssi.bits_used);
- s->mb_x = r->ssi.mb_x;
- s->mb_y = r->ssi.mb_y;
- r->si.start = s->mb_x + s->mb_y * s->mb_width;
- r->truncated = 1;
- }
-
- if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
- if(s->width != r->si.width || s->height != r->si.height /*&& avcodec_check_dimensions(s->avctx, r->si.width, r->si.height) >= 0 */){
- av_log(s->avctx, AV_LOG_DEBUG, "Changing dimensions to %dx%d\n", r->si.width,r->si.height);
- MPV_common_end(s);
- s->width = r->si.width;
- s->height = r->si.height;
- if(MPV_common_init(s) < 0)
- return -1;
- }
- s->pict_type = r->si.type ? r->si.type : I_TYPE;
- if(MPV_frame_start(s, s->avctx) < 0)
- return -1;
- ff_er_frame_start(s);
- s->current_picture_ptr = &s->current_picture;
- s->mb_x = s->mb_y = 0;
- r->truncated = 0;
- }
-
- r->si.size = size;
- r->si.end = end;
- s->qscale = r->si.quant;
- r->bits = r->si.size;
- r->block_start = r->si.start;
- s->mb_num_left = r->si.end - r->si.start;
- r->s.mb_skip_run = 0;
-
- r->prev_si = r->si;
-
- mb_pos = s->mb_x + s->mb_y * s->mb_width;
- if(!r->truncated && r->block_start != mb_pos){
- av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->block_start, mb_pos);
- s->mb_x = r->block_start % s->mb_width;
- s->mb_y = r->block_start / s->mb_width;
- }
- if(!r->truncated){
- memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(int));
- 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) && s->mb_num_left-- && s->mb_y < s->mb_height) {
- ff_update_block_index(s);
- s->dsp.clear_blocks(s->block[0]);
-
- /* save information about decoded position in case of truncated slice */
- if(r->bits > get_bits_count(gb)){
- r->ssi.bits_used = get_bits_count(gb);
- r->ssi.mb_x = s->mb_x;
- r->ssi.mb_y = s->mb_y;
- }
-
- if(rv34_decode_macroblock(r, r->intra_types + (s->mb_x + 1) * 4) < 0)
- break;
- 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(int));
- memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(int));
- }
- if(s->mb_x == s->resync_mb_x)
- s->first_slice_line=0;
- }
- if(!r->truncated)
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
- else // add only additionally decoded blocks
- ff_er_add_slice(s, old_mb_x+1, old_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
- r->truncated = 0;
- *last = 0;
- if(s->mb_y >= s->mb_height)
- *last = 1;
- if(r->bits > get_bits_count(gb) && show_bits(gb, r->bits-get_bits_count(gb)))
- *last = 1;
-
- r->ssi.data = av_realloc(r->ssi.data, r->bits >> 3);
- r->ssi.data_size = r->bits >> 3;
- memcpy(r->ssi.data, r->slice_data, r->bits >> 3);
- return 0;
-}
-
-#define CLIP_SYMM(a, b) av_clip(a, -(b), b)
-/**
- * Weaker deblocking
- */
-static inline void rv34_weak_loop_filter(uint8_t *src, const int step,
- const int flag0, const int flag1, const int mult,
- const int lim0, const int lim1, const int lim2, const int thr1,
- const int S0, const int S1, const int S2, const int S3)
-{
- uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
- int t, diff;
-
- t = src[0*step] - src[-1*step];
- if(!t) return;
- t = (mult * FFABS(t)) >> 7;
- if(t > 3) return;
- if(flag0 && flag1 && t > 2) return;
- t = src[-1*step] - src[0*step];
-
- if(flag0 && flag1)
- diff = (src[-2*step] - src[1*step] + t*4 + 4) >> 3;
- else
- diff = (t + 1) >> 1;
- diff = CLIP_SYMM(diff, lim2);
- src[-1*step] = cm[src[-1*step] + diff];
- src[ 0*step] = cm[src[ 0*step] - diff];
- if(FFABS(S1) <= thr1 && flag0){
- t = (S0 + S1 - diff) >> 1;
- src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim1)];
- }
- if(FFABS(S3) <= thr1 && flag1){
- t = (S2 + S3 + diff) >> 1;
- src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim0)];
- }
-}
-
-/**
- * This macro is used for calculating 25*x0+26*x1+26*x2+26*x3+25*x4
- * or 25*x0+26*x1+51*x2+26*x3
- * parameter sub - index of the value with coefficient = 25
- * parameter last - index of the value with coefficient 25 or 51
- */
-#define RV34_STRONG_FILTER(src, step, start, last, sub) \
- 26*(src[start*step] + src[(start+1)*step] + src[(start+2)*step] + src[(start+3)*step] + src[last*step]) - src[last*step] - src[sub*step]
-/**
- * Deblocking filter, the alternated version from JVT-A003r1 H.26L draft.
- */
-static inline void rv34_adaptive_loop_filter(uint8_t *src, const int step, const int stride, const int dmode, const int lim0, const int lim1, const int mult, const int thr0, const int thr1, const int chroma, const int edge)
-{
- int diffs[4][4];
- int s0 = 0, s1 = 0, s2 = 0, s3 = 0;
- uint8_t *ptr;
- int flag0 = 1, flag1 = 1;
- int llim0 = 3, llim1 = 3;
- int i, t, sflag;
- int p0, p1;
- int v88;
-
- for(i = 0, ptr = src; i < 4; i++, ptr += stride){
- diffs[i][0] = ptr[-2*step] - ptr[-1*step];
- diffs[i][1] = ptr[-2*step] - ptr[-3*step];
- diffs[i][2] = ptr[ 1*step] - ptr[ 0*step];
- diffs[i][3] = ptr[ 1*step] - ptr[ 2*step];
- s0 += diffs[i][0];
- s1 += diffs[i][1];
- s2 += diffs[i][2];
- s3 += diffs[i][3];
- }
- if(FFABS(s0) >= (thr0<<2)){
- llim0 = 1;
- flag0 = 0;
- }
- if(FFABS(s2) >= (thr0<<2)){
- llim1 = 1;
- flag1 = 0;
- }
- if(llim0 + llim1 == 2)
- return;
-
- if(!edge)
- flag0 = flag1 = 0;
- if(flag0 && FFABS(s1) >= thr1)
- flag0 = 0;
- if(flag1 && FFABS(s3) >= thr1)
- flag1 = 0;
-
- v88 = (lim0 + lim1 + llim0 + llim1) >> 1;
- if(flag0 + flag1 == 2){ /* strong filtering */
- for(i = 0; i < 4; i++, src += stride){
- t = src[0*step] - src[-1*step];
- if(!t) continue;
- sflag = (mult * FFABS(t)) >> 7;
- if(sflag > 1) continue;
-
- p0 = (RV34_STRONG_FILTER(src, step, -3, 1, -3) + rv34_dither_l[dmode + i]) >> 7;
- p1 = (RV34_STRONG_FILTER(src, step, -1, 3, -1) + rv34_dither_r[dmode + i]) >> 7;
- if(!sflag){
- src[-1*step] = p0;
- src[ 0*step] = p1;
- }else{
- if((src[-1*step] - p0) >= -v88 && (src[-1*step] - p0) <= v88)
- src[-1*step] = p0;
- else
- src[-1*step] = p1;
- if((src[ 0*step] - p1) >= -v88 && (src[ 0*step] - p1) <= v88)
- src[ 0*step] = p1;
- else
- src[ 0*step] = src[-1*step];
- }
- p0 = (RV34_STRONG_FILTER(src, step, -4, 0, -4) + rv34_dither_l[dmode + i]) >> 7;
- p1 = (RV34_STRONG_FILTER(src, step, -1, 3, -1) + rv34_dither_r[dmode + i]) >> 7;
- if(!sflag){
- src[-2*step] = p0;
- src[ 1*step] = p1;
- }else{
- if((src[-2*step] - p0) >= -v88 && (src[-2*step] - p0) <= v88)
- src[-2*step] = p0;
- else
- src[-2*step] += v88;
- if((src[ 1*step] - p1) >= -v88 && (src[ 1*step] - p1) <= v88)
- src[ 1*step] = p1;
- else
- src[ 1*step] += v88;
- }
- if(!chroma){
- src[-3*step] = (RV34_STRONG_FILTER(src, step, -4, -1, -3) + 64) >> 7;
- src[ 2*step] = (RV34_STRONG_FILTER(src, step, 0, 0, 2) + 64) >> 7;
- }
- }
- }else if(llim0 == 3 && llim1 == 3)
- for(i = 0; i < 4; i++, src += stride)
- rv34_weak_loop_filter(src, step, 1, 1, mult, lim0, lim1, v88, thr1,
- diffs[i][0], diffs[i][1], diffs[i][2], diffs[i][3]);
- else
- for(i = 0; i < 4; i++, src += stride)
- rv34_weak_loop_filter(src, step, llim0==3, llim1==3, mult, lim0>>1, lim1>>1, v88>>1, thr1,
- diffs[i][0], diffs[i][1], diffs[i][2], diffs[i][3]);
-}
-
-static void rv34_v_loop_filter(uint8_t *src, int stride, int dmode, int lim0, int lim1, int mult, int thr0, int thr1, int chroma, int edge){
- rv34_adaptive_loop_filter(src, 1, stride, dmode, lim0, lim1, mult, thr0, thr1, chroma, edge);
-}
-static void rv34_h_loop_filter(uint8_t *src, int stride, int dmode, int lim0, int lim1, int mult, int thr0, int thr1, int chroma, int edge){
- rv34_adaptive_loop_filter(src, stride, 1, dmode, lim0, lim1, mult, thr0, thr1, chroma, edge);
-}
-
-static void rv34_loop_filter(RV34DecContext *r)
-{
- MpegEncContext *s = &r->s;
- int mb_pos;
- int i, j;
- int no_up, no_left;
- uint8_t *Y, *U, *V;
- const int alpha = rv34_alpha_tab[s->qscale], beta = rv34_beta_tab[s->qscale];
- //XXX these are probably not correct
- const int thr = s->qscale, lim0 = rv34_filter_clip_tbl[1][s->qscale], lim1 = rv34_filter_clip_tbl[2][s->qscale];
-
- mb_pos = s->resync_mb_x + s->resync_mb_y * s->mb_stride;
- memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(int));
- s->first_slice_line = 1;
- s->mb_x= s->resync_mb_x;
- s->mb_y= s->resync_mb_y;
- ff_init_block_index(s);
- while(s->mb_num_left-- && s->mb_y < s->mb_height) {
- ff_update_block_index(s);
- if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
- no_up = s->first_slice_line || !IS_INTRA(s->current_picture_ptr->mb_type[mb_pos - s->mb_stride]);
- no_left = !s->mb_x || (s->first_slice_line && s->mb_x == s->resync_mb_x) || !IS_INTRA(s->current_picture_ptr->mb_type[mb_pos - 1]);
- for(j = 0; j < 4; j++){
- for(i = 0; i < 4; i++){
- Y = s->dest[0] + i*4 + j*4*s->linesize;
- if(!j && !no_up)
- rv34_h_loop_filter(Y, s->linesize, i*4+j, lim0, lim1, alpha, beta, thr, 0, 1);
- if(j != 3)
- rv34_h_loop_filter(Y + 4*s->linesize, s->linesize, i*4+j, lim0, lim1, alpha, beta, thr, 0, 0);
- if(i || !no_left)
- rv34_v_loop_filter(Y, s->linesize, i*4+j, lim0, lim1, alpha, beta, thr, 0, !i);
- }
- }
- }
- if (++s->mb_x == s->mb_width) {
- s->mb_x = 0;
- s->mb_y++;
- ff_init_block_index(s);
- mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- }
- if(s->mb_x == s->resync_mb_x)
- s->first_slice_line=0;
- }
-
-}
-/** @} */ // recons group end
/**
* Initialize decoder
- * @todo Maybe redone in some other way
*/
-static int rv34_decode_init(AVCodecContext *avctx)
+static int rv30_decode_init(AVCodecContext *avctx)
{
RV34DecContext *r = avctx->priv_data;
MpegEncContext *s = &r->s;
- static int tables_done = 0;
-
- r->rv30 = (avctx->codec_id == CODEC_ID_RV30);
- 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 = PIX_FMT_YUV420P;
- avctx->has_b_frames = 1;
- s->low_delay = 0;
-
- if (MPV_common_init(s) < 0)
+ r->rv30 = 1;
+ ff_rv34_decode_init(avctx);
+ if(avctx->extradata_size < 2){
+ av_log(avctx, AV_LOG_ERROR, "Extradata is too small\n");
return -1;
-
- ff_h264_pred_init(&r->h, CODEC_ID_RV40);
-
- r->intra_types_stride = (s->mb_width + 1) * 4;
- r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(int));
- 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(int));
-
- if(!tables_done){
- rv34_init_tables();
- tables_done = 1;
- }
- r->prev_si.type = -1;
- if(r->rv30){
- if(avctx->extradata_size < 2){
- av_log(avctx, AV_LOG_ERROR, "Extradata is too small\n");
- return -1;
- }
- r->rpr = (avctx->extradata[1] & 7) >> 1;
- r->rpr = FFMIN(r->rpr + 1, 3);
}
- r->parse_slice_header = r->rv30 ? rv30_parse_slice_header : rv40_parse_slice_header;
- r->decode_intra_types = r->rv30 ? rv30_decode_intra_types : rv40_decode_intra_types;
- r->decode_mb_info = r->rv30 ? rv30_decode_mb_info : rv40_decode_mb_info;
- if(r->rv30){
- r->luma_dc_quant_i = rv30_luma_dc_quant;
- r->luma_dc_quant_p = rv30_luma_dc_quant;
- }else{
- r->luma_dc_quant_i = rv40_luma_quant[0];
- r->luma_dc_quant_p = rv40_luma_quant[1];
- }
- return 0;
-}
-
-static int rv34_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- uint8_t *buf, int buf_size)
-{
- RV34DecContext *r = avctx->priv_data;
- MpegEncContext *s = &r->s;
- AVFrame *pict = data;
- SliceInfo si;
- int i;
- int slice_count, *slice_offset;
- int zero_offset = {0};
- int last = 0;
-
- /* no supplementary picture */
- if (buf_size == 0) {
- /* special case for last picture */
- if (s->low_delay==0 && s->next_picture_ptr) {
- *pict= *(AVFrame*)s->next_picture_ptr;
- s->next_picture_ptr= NULL;
-
- *data_size = sizeof(AVFrame);
- }
- }
-
- if(avctx->slice_count){
- slice_count = avctx->slice_count;
- slice_offset = avctx->slice_offset;
- }else{
- slice_count = 1;
- slice_offset = &zero_offset;
- }
-
- for(i=0; i<slice_count; i++){
- int offset= slice_offset[i];
- int size;
-
- if(i+1 == slice_count)
- size= buf_size - offset;
- else
- size= slice_offset[i+1] - offset;
-
- r->si.size = size * 8;
- r->si.end = s->mb_width * s->mb_height;
- if(i+1 < slice_count){
- init_get_bits(&s->gb, buf+slice_offset[i+1], (buf_size-slice_offset[i+1])*8);
- if(r->parse_slice_header(r, &r->s.gb, &si) < 0){
- if(i+2 < slice_count)
- size = slice_offset[i+2] - offset;
- else
- size = buf_size - offset;
- r->si.size = size * 8;
- }else
- r->si.end = si.start;
- }
- r->slice_data = buf + offset;
- rv34_decode_slice(r, r->si.size, r->si.end, &last);
- if(last)
- break;
- s->mb_num_left = r->si.end - r->si.start;
- //rv40_postprocess(r);
- }
-
- if(last){
- r->prev_si.type = -1;
- ff_er_frame_end(s);
- MPV_frame_end(s);
- if (s->pict_type == B_TYPE || s->low_delay) {
- *pict= *(AVFrame*)s->current_picture_ptr;
- } else if (s->last_picture_ptr != NULL) {
- *pict= *(AVFrame*)s->last_picture_ptr;
- }
-
- if(s->last_picture_ptr || s->low_delay){
- *data_size = sizeof(AVFrame);
- ff_print_debug_info(s, pict);
- }
- s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
- }
- return buf_size;
-}
-
-static int rv34_decode_end(AVCodecContext *avctx)
-{
- RV34DecContext *r = avctx->priv_data;
-
- MPV_common_end(&r->s);
-
- av_freep(&r->intra_types_hist);
- r->intra_types = NULL;
- av_freep(&r->mb_type);
- av_freep(&r->ssi.data);
-
+ r->rpr = (avctx->extradata[1] & 7) >> 1;
+ r->rpr = FFMIN(r->rpr + 1, 3);
+ r->parse_slice_header = rv30_parse_slice_header;
+ r->decode_intra_types = rv30_decode_intra_types;
+ r->decode_mb_info = rv30_decode_mb_info;
+ r->luma_dc_quant_i = rv30_luma_dc_quant;
+ r->luma_dc_quant_p = rv30_luma_dc_quant;
return 0;
}
@@ -2153,19 +147,8 @@ AVCodec rv30_decoder = {
CODEC_TYPE_VIDEO,
CODEC_ID_RV30,
sizeof(RV34DecContext),
- rv34_decode_init,
- NULL,
- rv34_decode_end,
- rv34_decode_frame,
-};
-
-AVCodec rv40_decoder = {
- "rv40",
- CODEC_TYPE_VIDEO,
- CODEC_ID_RV40,
- sizeof(RV34DecContext),
- rv34_decode_init,
+ rv30_decode_init,
NULL,
- rv34_decode_end,
- rv34_decode_frame,
+ ff_rv34_decode_end,
+ ff_rv34_decode_frame,
};
Copied: rv40/rv34.c (from r1377, /rv40/rv40.c)
==============================================================================
--- /rv40/rv40.c (original)
+++ rv40/rv34.c Wed Sep 19 18:55:05 2007
@@ -1,5 +1,5 @@
/*
- * RV40 decoder
+ * RV30/40 decoder common data
* Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
*
* This file is part of FFmpeg.
@@ -20,20 +20,17 @@
*/
/**
- * @file rv40.c
- * RV30 and RV40 decoder.
+ * @file rv34.c
+ * RV30 and RV40 decoder common data.
*/
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
-#include "rv40vlc.h"
-#include "rv40vlc2.h"
-#include "rv40data.h"
-#include "rv30data.h"
-
-#include "h264pred.h"
+#include "rv34vlc.h"
+#include "rv34data.h"
+#include "rv34.h"
//#define DEBUG
@@ -44,105 +41,9 @@ static const int rv34_mb_type_to_lavc[12
MB_TYPE_16x8, MB_TYPE_8x16, MB_TYPE_DIRECT2, MB_TYPE_16x16
};
-/**
- * RV30 and RV40 Macroblock types
- * @{
- */
-enum RV40BlockTypes{
- RV34_MB_TYPE_INTRA, ///< Intra macroblock
- RV34_MB_TYPE_INTRA16x16, ///< Intra macroblock with DCs in a separate 4x4 block
- RV34_MB_P_16x16, ///< P-frame macroblock, one motion frame
- RV34_MB_P_8x8, ///< P-frame macroblock, 8x8 motion compensation partitions
- RV34_MB_B_FORWARD, ///< B-frame macroblock, forward prediction
- RV34_MB_B_BACKWARD, ///< B-frame macroblock, backward prediction
- RV34_MB_SKIP, ///< Skipped block
- RV34_MB_B_INTERP, ///< Bidirectionally predicted B-frame macroblock, no motion vectors
- RV34_MB_P_16x8, ///< P-frame macroblock, 16x8 motion compensation partitions
- RV34_MB_P_8x16, ///< P-frame macroblock, 8x16 motion compensation partitions
- RV34_MB_B_DIRECT, ///< Bidirectionally predicted B-frame macroblock, two motion vectors
- RV34_MB_P_MIX16x16, ///< P-frame macroblock with DCs in a separate 4x4 block, one motion vector
- RV34_MB_TYPES
-};
-/** @} */
-
-/**
- * VLC tables used by decoder
- *
- * intra frame VLC sets do not contain some of those tables
- */
-typedef struct RV34VLC{
- VLC cbppattern[2]; ///< VLCs used for pattern of coded block patterns decoding
- VLC cbp[2][4]; ///< VLCs used for coded block patterns decoding
- VLC first_pattern[4]; ///< VLCs used for decoding coefficients in the first subblock
- VLC second_pattern[2]; ///< VLCs used for decoding coefficients in the subblocks 2 and 3
- VLC third_pattern[2]; ///< VLCs used for decoding coefficients in the last subblock
- VLC coefficient; ///< VLCs used for decoding big coefficients
-}RV34VLC;
-
-/** Essential slice information */
-typedef struct SliceInfo{
- int type; ///< slice type (intra, inter)
- int size; ///< size of the slice in bits
- int quant; ///< quantizer used for this slice
- int vlc_set; ///< VLCs used for this slice
- int start, end; ///< start and end macroblocks of the slice
- int header_size; ///< header size in bits
- int width; ///< coded width
- int height; ///< coded height
-}SliceInfo;
-
-/** Slice information saved for truncated slices */
-typedef struct SavedSliceInfo{
- uint8_t *data; ///< bitstream data
- int data_size; ///< data size
- int bits_used; ///< bits used up to last decoded block
- int mb_x, mb_y; ///< coordinates of the last decoded block
-}SavedSliceInfo;
-
-/** Decoder context */
-typedef struct RV34DecContext{
- MpegEncContext s;
- int mb_bits; ///< bits needed to read MB offet in slice header
- int *intra_types_hist; ///< old block types, used for prediction
- int *intra_types; ///< block types
- int intra_types_stride; ///< stride for block types data
- int block_start; ///< start of slice in blocks
- uint8_t *luma_dc_quant_i;///< luma subblock DC quantizer for intraframes
- uint8_t *luma_dc_quant_p;///< luma subblock DC quantizer for interframes
-
- int vlc_set; ///< index of currently selected VLC set
- RV34VLC *cur_vlcs; ///< VLC set used for current frame decoding
- int bits; ///< slice size in bits
- H264PredContext h; ///< functions for 4x4 and 16x16 intra block prediction
- SliceInfo si; ///< current slice information
- SliceInfo prev_si; ///< info for the saved slice
- uint8_t *slice_data; ///< saved slice data
-
- int *mb_type; ///< internal macroblock types
- int block_type; ///< current block type
- int luma_vlc; ///< which VLC set will be used for luma blocks decoding
- int chroma_vlc; ///< which VLC set will be used for chroma blocks decoding
- int is16; ///< current block has additional 16x16 specific features or not
- int dmv[4][2]; ///< differential motion vectors for the current macroblock
-
- int truncated; ///< flag signalling that slice ended prematurely
- SavedSliceInfo ssi; ///< data for truncated slice
-
- int rv30; ///< indicates which RV variasnt is currently decoded
- int rpr; ///< one field size in RV30 slice header
-
- int avail[4]; ///< whether left, top, top rights and top left MBs are available
-
- int (*parse_slice_header)(struct RV34DecContext *r, GetBitContext *gb, SliceInfo *si);
- int (*decode_intra_types)(struct RV34DecContext *r, GetBitContext *gb, int *dst);
- int (*decode_mb_info)(struct RV34DecContext *r);
-}RV34DecContext;
static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];
static VLC omega_part_vlc;
-static VLC aic_top_vlc;
-static VLC aic_mode1_vlc[AIC_MODE1_NUM], aic_mode2_vlc[AIC_MODE2_NUM];
-static VLC ptype_vlc[NUM_PTYPE_VLCS], btype_vlc[NUM_BTYPE_VLCS];
/**
* @defgroup vlc RV40 VLC generating functions
@@ -221,37 +122,10 @@ static void rv34_init_tables()
rv34_gen_vlc(rv34_inter_coeffvlc_pointers[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient);
}
- init_vlc(&aic_top_vlc, AIC_TOP_BITS, AIC_TOP_SIZE,
- rv40_aic_top_vlc_bits, 1, 1,
- rv40_aic_top_vlc_codes, 1, 1, INIT_VLC_USE_STATIC);
- for(i = 0; i < AIC_MODE1_NUM; i++){
- // For some reason every tenth VLC table is empty
- // So skip it for consistency
- // XXX: redo without this hack
- if((i % 10) == 9) continue;
- init_vlc(&aic_mode1_vlc[i], AIC_MODE1_BITS, AIC_MODE1_SIZE,
- aic_mode1_vlc_bits[i], 1, 1,
- aic_mode1_vlc_codes[i], 1, 1, INIT_VLC_USE_STATIC);
- }
- for(i = 0; i < AIC_MODE2_NUM; i++){
- init_vlc(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE,
- aic_mode2_vlc_bits[i], 1, 1,
- aic_mode2_vlc_codes[i], 2, 2, INIT_VLC_USE_STATIC);
- }
init_vlc_sparse(&omega_part_vlc, OMEGA_BITS, NUM_OMEGA,
omega_part_vlc_bits, 1, 1,
omega_part_vlc_codes, 1, 1,
omega_part_vlc_syms, 1, 1, INIT_VLC_USE_STATIC);
- for(i = 0; i < NUM_PTYPE_VLCS; i++)
- init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE,
- ptype_vlc_bits[i], 1, 1,
- ptype_vlc_codes[i], 1, 1,
- ptype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC);
- for(i = 0; i < NUM_BTYPE_VLCS; i++)
- init_vlc_sparse(&btype_vlc[i], BTYPE_VLC_BITS, BTYPE_VLC_SIZE,
- btype_vlc_bits[i], 1, 1,
- btype_vlc_codes[i], 1, 1,
- btype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC);
}
/** @} */ // vlc group
@@ -520,12 +394,16 @@ static int get_dimension(GetBitContext *
}
/**
- * Get encoded picture size - usually this is called from rv40_parse_slice_header
+ * Decode staring slice position
+ * @todo maybe replace with ff_h263_decode_mba() ?
*/
-static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h)
+int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size)
{
- *w = get_dimension(gb, rv40_standard_widths, NULL);
- *h = get_dimension(gb, rv40_standard_heights, rv40_standard_heights2);
+ int i;
+ for(i = 0; i < 5; i++)
+ if(rv34_mb_max_sizes[i] > mb_size)
+ break;
+ return rv34_mb_bits_sizes[i];
}
/**
@@ -543,69 +421,6 @@ static inline RV34VLC* choose_vlc_set(in
: &intra_vlcs[rv34_quant_to_vlc_set[0][av_clip(quant, 0, 30)]];
}
-static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
-{
- int t, mb_bits;
- int w = r->s.width, h = r->s.height;
- int i, mb_size;
-
- memset(si, 0, sizeof(SliceInfo));
- get_bits(gb, 3);
- si->type = get_bits(gb, 2);
- if(si->type == 1) si->type = 0;
- if(get_bits1(gb))
- return -1;
- si->quant = get_bits(gb, 5);
- get_bits1(gb);
- t = get_bits(gb, 13);
- skip_bits(gb, r->rpr);
- si->vlc_set = 0;
- si->width = w;
- si->height = h;
- mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
- for(i = 0; i < 5; i++)
- if(rv34_mb_max_sizes[i] > mb_size)
- break;
- mb_bits = rv34_mb_bits_sizes[i];
- si->start = get_bits(gb, mb_bits);
- get_bits1(gb);
- si->header_size = get_bits_count(gb);
- return 0;
-}
-
-static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
-{
- int t, mb_bits;
- int w = r->s.width, h = r->s.height;
- int i, mb_size;
-
- memset(si, 0, sizeof(SliceInfo));
- si->type = -1;
- if(get_bits1(gb))
- return -1;
- si->type = get_bits(gb, 2);
- if(si->type == 1) si->type = 0;
- si->quant = get_bits(gb, 5);
- if(get_bits(gb, 2))
- return -1;
- si->vlc_set = get_bits(gb, 2);
- get_bits1(gb);
- t = get_bits(gb, 13); /// ???
- if(!si->type || !get_bits1(gb))
- rv40_parse_picture_size(gb, &w, &h);
- si->width = w;
- si->height = h;
- mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
- for(i = 0; i < 5; i++)
- if(rv34_mb_max_sizes[i] > mb_size)
- break;
- mb_bits = rv34_mb_bits_sizes[i];
- si->start = get_bits(gb, mb_bits);
- si->header_size = get_bits_count(gb);
-
- return 0;
-}
-
/**
* Decode variable-length code constructed from variable-length codes
* similar to Even-Rodeh and Elias Omega codes
@@ -645,101 +460,6 @@ int ff_rv34_get_omega_signed(GetBitConte
}
/**
- * Decode 4x4 intra types array
- */
-static int rv30_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int *dst)
-{
- int i, j, k;
- int A, B;
- int *ptr;
- int code;
-
- for(i = 0; i < 4; i++, dst += r->intra_types_stride){
- ptr = dst;
- for(j = 0; j < 4; j+= 2){
- code = (ff_rv34_get_omega(gb) - 1) << 1;
- if(code >= 81*2){
- av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n");
- return -1;
- }
- for(k = 0; k < 2; k++){
- A = ptr[-r->intra_types_stride] + 1;
- B = ptr[-1] + 1;
- *ptr++ = rv30_itype_from_context[A * 90 + B * 9 + rv30_itype_code[code + k]];
- if(ptr[-1] == 9){
- av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction mode\n");
- return -1;
- }
- }
- }
- }
- return 0;
-}
-
-/**
- * Decode 4x4 intra types array
- */
-static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int *dst)
-{
- MpegEncContext *s = &r->s;
- int i, j, k, v;
- int A, B, C;
- int pattern;
- int *ptr;
-
- for(i = 0; i < 4; i++, dst += r->intra_types_stride){
- if(!i && s->first_slice_line){
- pattern = get_vlc2(gb, aic_top_vlc.table, AIC_TOP_BITS, 1);
- dst[0] = (pattern >> 2) & 2;
- dst[1] = (pattern >> 1) & 2;
- dst[2] = pattern & 2;
- dst[3] = (pattern << 1) & 2;
- continue;
- }
- ptr = dst;
- for(j = 0; j < 4; j++){
- /* Coefficients are read using VLC chosen by prediction pattern
- * First one (used for retrieving a pair of coefficients) is
- * constructed from top, top right and left coefficients
- * Second one (used for retrieving only one coefficient) is
- * top + 10 * left
- */
- A = ptr[-r->intra_types_stride + 1]; // it won't be used for the last coefficient in a row
- B = ptr[-r->intra_types_stride];
- C = ptr[-1];
- pattern = A + (B << 4) + (C << 8);
- for(k = 0; k < MODE2_PATTERNS_NUM; k++)
- if(pattern == rv40_aic_table_index[k])
- break;
- if(j < 3 && k < MODE2_PATTERNS_NUM){ //pattern is found, decoding 2 coefficients
- v = get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2);
- *ptr++ = v/9;
- *ptr++ = v%9;
- j++;
- }else{
- if(B != -1 && C != -1)
- v = get_vlc2(gb, aic_mode1_vlc[B + C*10].table, AIC_MODE1_BITS, 1);
- else{ // tricky decoding
- v = 0;
- switch(C){
- case -1: // code 0 -> 1, 1 -> 0
- if(B == -1 || B == 0 || B == 1)
- v = get_bits1(gb) ^ 1;
- break;
- case 0:
- case 2: // code 0 -> 2, 1 -> 0
- v = (get_bits1(gb) ^ 1) << 1;
- break;
- }
- }
- *ptr++ = v;
- }
- }
- }
- return 0;
-}
-
-/**
* Decode quantizer difference and return modified quantizer
*/
static inline int rv34_decode_dquant(GetBitContext *gb, int quant)
@@ -750,86 +470,6 @@ static inline int rv34_decode_dquant(Get
return get_bits(gb, 5);
}
-/**
- * Decode macroblock information
- */
-static int rv30_decode_mb_info(RV34DecContext *r)
-{
- static const int rv30_p_types[6] = { RV34_MB_SKIP, RV34_MB_P_16x16, RV34_MB_P_8x8, -1, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 };
- static const int rv30_b_types[6] = { RV34_MB_SKIP, RV34_MB_B_INTERP, RV34_MB_B_FORWARD, RV34_MB_B_BACKWARD, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 };
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int code;
-
- code = ff_rv34_get_omega(gb) - 1;
- if(code > 11){
- av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n");
- return -1;
- }
- if(code > 5){
- av_log(s->avctx, AV_LOG_ERROR, "dquant needed\n");
- code -= 6;
- }
- if(s->pict_type != B_TYPE)
- return rv30_p_types[code];
- else
- return rv30_b_types[code];
-}
-
-/**
- * Decode macroblock information
- */
-static int rv40_decode_mb_info(RV34DecContext *r)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int q, i;
- int prev_type = 0;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int blocks[RV34_MB_TYPES];
- int count = 0;
-
- if(!r->s.mb_skip_run)
- r->s.mb_skip_run = ff_rv34_get_omega(gb);
-
- if(--r->s.mb_skip_run)
- return RV34_MB_SKIP;
-
- memset(blocks, 0, sizeof(blocks));
- if(r->avail[0])
- blocks[r->mb_type[mb_pos - 1]]++;
- if(r->avail[1])
- blocks[r->mb_type[mb_pos - s->mb_stride]]++;
- if(r->avail[1] && r->avail[2])
- blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++;
- if(r->avail[1] && r->avail[3])
- blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++;
-
- for(i = 0; i < RV34_MB_TYPES; i++){
- if(blocks[i] > count){
- count = blocks[i];
- prev_type = i;
- }
- }
- if(s->pict_type == P_TYPE){
- if(prev_type == RV34_MB_SKIP) prev_type = RV34_MB_P_16x16;
- prev_type = block_num_to_ptype_vlc_num[prev_type];
- q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1);
- if(q < PBTYPE_ESCAPE)
- return q;
- q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1);
- av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n");
- }else{
- prev_type = block_num_to_btype_vlc_num[prev_type];
- q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1);
- if(q < PBTYPE_ESCAPE)
- return q;
- q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1);
- av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n");
- }
- return 0;
-}
-
/** @} */ //bitstream functions
/**
@@ -1993,7 +1633,7 @@ static void rv34_loop_filter(RV34DecCont
* Initialize decoder
* @todo Maybe redone in some other way
*/
-static int rv34_decode_init(AVCodecContext *avctx)
+int ff_rv34_decode_init(AVCodecContext *avctx)
{
RV34DecContext *r = avctx->priv_data;
MpegEncContext *s = &r->s;
@@ -2032,28 +1672,10 @@ static int rv34_decode_init(AVCodecConte
tables_done = 1;
}
r->prev_si.type = -1;
- if(r->rv30){
- if(avctx->extradata_size < 2){
- av_log(avctx, AV_LOG_ERROR, "Extradata is too small\n");
- return -1;
- }
- r->rpr = (avctx->extradata[1] & 7) >> 1;
- r->rpr = FFMIN(r->rpr + 1, 3);
- }
- r->parse_slice_header = r->rv30 ? rv30_parse_slice_header : rv40_parse_slice_header;
- r->decode_intra_types = r->rv30 ? rv30_decode_intra_types : rv40_decode_intra_types;
- r->decode_mb_info = r->rv30 ? rv30_decode_mb_info : rv40_decode_mb_info;
- if(r->rv30){
- r->luma_dc_quant_i = rv30_luma_dc_quant;
- r->luma_dc_quant_p = rv30_luma_dc_quant;
- }else{
- r->luma_dc_quant_i = rv40_luma_quant[0];
- r->luma_dc_quant_p = rv40_luma_quant[1];
- }
return 0;
}
-static int rv34_decode_frame(AVCodecContext *avctx,
+int ff_rv34_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
{
@@ -2134,7 +1756,7 @@ static int rv34_decode_frame(AVCodecCont
return buf_size;
}
-static int rv34_decode_end(AVCodecContext *avctx)
+int ff_rv34_decode_end(AVCodecContext *avctx)
{
RV34DecContext *r = avctx->priv_data;
@@ -2147,25 +1769,3 @@ static int rv34_decode_end(AVCodecContex
return 0;
}
-
-AVCodec rv30_decoder = {
- "rv30",
- CODEC_TYPE_VIDEO,
- CODEC_ID_RV30,
- sizeof(RV34DecContext),
- rv34_decode_init,
- NULL,
- rv34_decode_end,
- rv34_decode_frame,
-};
-
-AVCodec rv40_decoder = {
- "rv40",
- CODEC_TYPE_VIDEO,
- CODEC_ID_RV40,
- sizeof(RV34DecContext),
- rv34_decode_init,
- NULL,
- rv34_decode_end,
- rv34_decode_frame,
-};
Copied: rv40/rv34.h (from r1377, /rv40/rv40.c)
==============================================================================
--- /rv40/rv40.c (original)
+++ rv40/rv34.h Wed Sep 19 18:55:05 2007
@@ -1,5 +1,5 @@
/*
- * RV40 decoder
+ * RV30/40 decoder common data declarations
* Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
*
* This file is part of FFmpeg.
@@ -20,30 +20,19 @@
*/
/**
- * @file rv40.c
- * RV30 and RV40 decoder.
+ * @file rv34.h
+ * RV30 and RV40 decoder common data declarations.
*/
+#ifndef RV30_H
+#define RV30_H
+
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
-#include "rv40vlc.h"
-#include "rv40vlc2.h"
-#include "rv40data.h"
-#include "rv30data.h"
-
#include "h264pred.h"
-//#define DEBUG
-
-/** Translation of RV40 macroblock types to lavc ones */
-static const int rv34_mb_type_to_lavc[12] = {
- MB_TYPE_INTRA, MB_TYPE_INTRA16x16, MB_TYPE_16x16, MB_TYPE_8x8,
- MB_TYPE_16x16, MB_TYPE_16x16, MB_TYPE_SKIP, MB_TYPE_DIRECT2,
- MB_TYPE_16x8, MB_TYPE_8x16, MB_TYPE_DIRECT2, MB_TYPE_16x16
-};
-
/**
* RV30 and RV40 Macroblock types
* @{
@@ -134,2038 +123,17 @@ typedef struct RV34DecContext{
int avail[4]; ///< whether left, top, top rights and top left MBs are available
int (*parse_slice_header)(struct RV34DecContext *r, GetBitContext *gb, SliceInfo *si);
- int (*decode_intra_types)(struct RV34DecContext *r, GetBitContext *gb, int *dst);
int (*decode_mb_info)(struct RV34DecContext *r);
+ int (*decode_intra_types)(struct RV34DecContext *r, GetBitContext *gb, int *dst);
}RV34DecContext;
-static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];
-static VLC omega_part_vlc;
-static VLC aic_top_vlc;
-static VLC aic_mode1_vlc[AIC_MODE1_NUM], aic_mode2_vlc[AIC_MODE2_NUM];
-static VLC ptype_vlc[NUM_PTYPE_VLCS], btype_vlc[NUM_BTYPE_VLCS];
-
-/**
- * @defgroup vlc RV40 VLC generating functions
- * @{
- */
-
-/**
- * Generate VLC from codeword lengths
- */
-static int rv34_gen_vlc(const uint8_t *bits2, int size, VLC *vlc)
-{
- int i;
- int counts[17] = {0}, codes[17];
- uint16_t cw[size], syms[size];
- uint8_t bits[size];
- int maxbits = 0, realsize;
- int ret;
-
- realsize = 0;
- for(i = 0; i < size; i++){
- if(bits2[i]){
- bits[realsize] = bits2[i];
- syms[realsize] = i;
- realsize++;
- maxbits = FFMAX(maxbits, bits2[i]);
- counts[bits2[i]]++;
- }
- }
-
- size = realsize;
- 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[bits[i]]++;
-
- ret = init_vlc_sparse(vlc, FFMIN(maxbits, 9), size,
- bits, 1, 1,
- cw, 2, 2,
- syms, 2, 2, INIT_VLC_USE_STATIC);
- return ret;
-}
-
-/**
- * Initialize all tables
- */
-static void rv34_init_tables()
-{
- int i, j, k;
-
- for(i = 0; i < NUM_INTRA_TABLES; i++){
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_intra_cbppatvlc_pointers[i][j], CBPPAT_VLC_SIZE, &intra_vlcs[i].cbppattern[j]);
- for(j = 0; j < 2; j++)
- for(k = 0; k < 4; k++)
- rv34_gen_vlc(rv34_intra_cbpvlc_pointers[i][j][k], CBP_VLC_SIZE, &intra_vlcs[i].cbp[j][k]);
- for(j = 0; j < 4; j++)
- rv34_gen_vlc(rv34_intra_firstpatvlc_pointers[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_intra_secondpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_intra_thirdpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j]);
- rv34_gen_vlc(rv34_intra_coeffvlc_pointers[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient);
- }
-
- for(i = 0; i < NUM_INTER_TABLES; i++){
- rv34_gen_vlc(rv34_inter_cbppatvlc_pointers[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0]);
- for(j = 0; j < 4; j++)
- rv34_gen_vlc(rv34_inter_cbpvlc_pointers[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_inter_firstpatvlc_pointers[i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_inter_secondpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_inter_thirdpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j]);
- rv34_gen_vlc(rv34_inter_coeffvlc_pointers[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient);
- }
-
- init_vlc(&aic_top_vlc, AIC_TOP_BITS, AIC_TOP_SIZE,
- rv40_aic_top_vlc_bits, 1, 1,
- rv40_aic_top_vlc_codes, 1, 1, INIT_VLC_USE_STATIC);
- for(i = 0; i < AIC_MODE1_NUM; i++){
- // For some reason every tenth VLC table is empty
- // So skip it for consistency
- // XXX: redo without this hack
- if((i % 10) == 9) continue;
- init_vlc(&aic_mode1_vlc[i], AIC_MODE1_BITS, AIC_MODE1_SIZE,
- aic_mode1_vlc_bits[i], 1, 1,
- aic_mode1_vlc_codes[i], 1, 1, INIT_VLC_USE_STATIC);
- }
- for(i = 0; i < AIC_MODE2_NUM; i++){
- init_vlc(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE,
- aic_mode2_vlc_bits[i], 1, 1,
- aic_mode2_vlc_codes[i], 2, 2, INIT_VLC_USE_STATIC);
- }
- init_vlc_sparse(&omega_part_vlc, OMEGA_BITS, NUM_OMEGA,
- omega_part_vlc_bits, 1, 1,
- omega_part_vlc_codes, 1, 1,
- omega_part_vlc_syms, 1, 1, INIT_VLC_USE_STATIC);
- for(i = 0; i < NUM_PTYPE_VLCS; i++)
- init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE,
- ptype_vlc_bits[i], 1, 1,
- ptype_vlc_codes[i], 1, 1,
- ptype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC);
- for(i = 0; i < NUM_BTYPE_VLCS; i++)
- init_vlc_sparse(&btype_vlc[i], BTYPE_VLC_BITS, BTYPE_VLC_SIZE,
- btype_vlc_bits[i], 1, 1,
- btype_vlc_codes[i], 1, 1,
- btype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC);
-}
-
-/** @} */ // vlc group
-
-
-/**
- * @defgroup transform RV40 inverse transform functions
- * @{
- */
-
-/**
- * Real Video 4.0 inverse transform
- * Code is almost the same as in SVQ3, only scaling is different
- */
-static void rv34_intra_inv_transform(DCTELEM *block, const int offset){
- int temp[16];
- unsigned int i;
-
- for(i=0; i<4; i++){
- const int z0= 13*(block[offset+i+8*0] + block[offset+i+8*2]);
- const int z1= 13*(block[offset+i+8*0] - block[offset+i+8*2]);
- const int z2= 7* block[offset+i+8*1] - 17*block[offset+i+8*3];
- const int z3= 17* block[offset+i+8*1] + 7*block[offset+i+8*3];
-
- temp[4*i+0]= z0+z3;
- temp[4*i+1]= z1+z2;
- temp[4*i+2]= z1-z2;
- temp[4*i+3]= z0-z3;
- }
-
- for(i=0; i<4; i++){
- const int z0= 13*(temp[4*0+i] + temp[4*2+i]) + 0x200;
- const int z1= 13*(temp[4*0+i] - temp[4*2+i]) + 0x200;
- const int z2= 7* temp[4*1+i] - 17*temp[4*3+i];
- const int z3= 17* temp[4*1+i] + 7*temp[4*3+i];
-
- block[offset+i*8+0]= (z0 + z3)>>10;
- block[offset+i*8+1]= (z1 + z2)>>10;
- block[offset+i*8+2]= (z1 - z2)>>10;
- block[offset+i*8+3]= (z0 - z3)>>10;
- }
-
-}
-
-/**
- * RealVideo 4.0 inverse transform - special version
- *
- * Code is almost the same but final coefficients are multiplied by 1.5
- * and have no rounding
- */
-static void rv34_intra_inv_transform_noround(DCTELEM *block, const int offset){
- int temp[16];
- unsigned int i;
-
- for(i=0; i<4; i++){
- const int z0= 13*(block[offset+i+8*0] + block[offset+i+8*2]);
- const int z1= 13*(block[offset+i+8*0] - block[offset+i+8*2]);
- const int z2= 7* block[offset+i+8*1] - 17*block[offset+i+8*3];
- const int z3= 17* block[offset+i+8*1] + 7*block[offset+i+8*3];
-
- temp[4*i+0]= z0+z3;
- temp[4*i+1]= z1+z2;
- temp[4*i+2]= z1-z2;
- temp[4*i+3]= z0-z3;
- }
-
- for(i=0; i<4; i++){
- const int z0= 13*(temp[4*0+i] + temp[4*2+i]);
- const int z1= 13*(temp[4*0+i] - temp[4*2+i]);
- const int z2= 7* temp[4*1+i] - 17*temp[4*3+i];
- const int z3= 17* temp[4*1+i] + 7*temp[4*3+i];
-
- block[offset+i*8+0]= ((z0 + z3)*3)>>11;
- block[offset+i*8+1]= ((z1 + z2)*3)>>11;
- block[offset+i*8+2]= ((z1 - z2)*3)>>11;
- block[offset+i*8+3]= ((z0 - z3)*3)>>11;
- }
-
-}
-
-/** @} */ // transform
-
-
-/**
- * @defgroup block RV40 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 table2;
- static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000};
- static const int shifts[4] = { 0, 2, 8, 10 };
- int *curshift = shifts;
- int i, t, mask;
-
- code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2);
- pattern = code & 0xF;
- code >>= 4;
-
- table2 = rv34_count_ones[pattern];
-
- for(mask = 8; mask; mask >>= 1, curshift++){
- if(!(pattern & mask)) continue;
- t = get_vlc2(gb, vlc->cbp[table][table2].table, vlc->cbp[table][table2].bits, 1);
- cbp |= rv34_cbp_code[t] << curshift[0];
- }
-
- for(i = 0; i < 4; i++){
- t = modulo_three_table[code][i];
- 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 bistream and store it
- */
-static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc)
-{
- 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;
- }
-}
-
-/**
- * Decode 2x2 subblock of coefficients
- */
-static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc)
-{
- int coeffs[4];
-
- coeffs[0] = modulo_three_table[code][0];
- coeffs[1] = modulo_three_table[code][1];
- coeffs[2] = modulo_three_table[code][2];
- coeffs[3] = modulo_three_table[code][3];
- decode_coeff(dst , coeffs[0], 3, gb, vlc);
- if(!is_block2){
- decode_coeff(dst+1, coeffs[1], 2, gb, vlc);
- decode_coeff(dst+8, coeffs[2], 2, gb, vlc);
- }else{
- decode_coeff(dst+8, coeffs[1], 2, gb, vlc);
- decode_coeff(dst+1, coeffs[2], 2, gb, vlc);
- }
- decode_coeff(dst+9, coeffs[3], 2, gb, vlc);
-}
-
-/**
- * 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 inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc)
-{
- int code, pattern;
-
- code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2);
-
- pattern = code & 0x7;
-
- code >>= 3;
- decode_subblock(dst, code, 0, gb, &rvlc->coefficient);
-
- if(pattern & 4){
- code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
- decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient);
- }
- 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 + 8*2, code, 1, gb, &rvlc->coefficient);
- }
- if(pattern & 1){
- code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
- decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient);
- }
-}
-
-/**
- * Dequantize ordinary 4x4 block
- * @todo optimize
- */
-static inline void rv34_dequant4x4(DCTELEM *block, int offset, int Qdc, int Q)
-{
- int i, j;
-
- block += offset;
- block[0] = (block[0] * Qdc + 8) >> 4;
- for(i = 0; i < 4; i++)
- for(j = !i; j < 4; j++)
- block[j + i*8] = (block[j + i*8] * Q + 8) >> 4;
-}
-
-/**
- * Dequantize 4x4 block of DC values for 16x16 macroblock
- * @todo optimize
- */
-static inline void rv34_dequant4x4_16x16(DCTELEM *block, int offset, int Qdc, int Q)
-{
- int i;
-
- block += offset;
- for(i = 0; i < 3; i++)
- block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Qdc + 8) >> 4;
- for(; i < 16; i++)
- block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Q + 8) >> 4;
-}
-/** @} */ //block functions
-
-
-/**
- * @defgroup bitstream RV40 bitstream parsing
- * @{
- */
-
-static inline int decode210(GetBitContext *gb){
- if (get_bits1(gb))
- return 0;
- else
- return 2 - get_bits1(gb);
-}
-
-/**
- * Get stored dimension from bitstream
- *
- * If the width/height is the standard one then it's coded as 3-bit index.
- * Otherwise it is coded as escaped 8-bit portions.
- */
-static int get_dimension(GetBitContext *gb, const int *dim1, const int *dim2)
-{
- int val, t;
-
- t = get_bits(gb, 3);
- val = dim1[t];
- if(!val && dim2)
- val = dim2[(t*2 | get_bits1(gb)) & 3];
- if(!val){
- do{
- t = get_bits(gb, 8);
- val += t << 2;
- }while(t == 0xFF);
- }
- return val;
-}
-
-/**
- * Get encoded picture size - usually this is called from rv40_parse_slice_header
- */
-static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h)
-{
- *w = get_dimension(gb, rv40_standard_widths, NULL);
- *h = get_dimension(gb, rv40_standard_heights, rv40_standard_heights2);
-}
-
-/**
- * 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){
- if(quant < 19) quant += 10;
- else if(quant < 26) quant += 5;
- }
- if(mod == 1)
- if(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)]];
-}
-
-static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
-{
- int t, mb_bits;
- int w = r->s.width, h = r->s.height;
- int i, mb_size;
-
- memset(si, 0, sizeof(SliceInfo));
- get_bits(gb, 3);
- si->type = get_bits(gb, 2);
- if(si->type == 1) si->type = 0;
- if(get_bits1(gb))
- return -1;
- si->quant = get_bits(gb, 5);
- get_bits1(gb);
- t = get_bits(gb, 13);
- skip_bits(gb, r->rpr);
- si->vlc_set = 0;
- si->width = w;
- si->height = h;
- mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
- for(i = 0; i < 5; i++)
- if(rv34_mb_max_sizes[i] > mb_size)
- break;
- mb_bits = rv34_mb_bits_sizes[i];
- si->start = get_bits(gb, mb_bits);
- get_bits1(gb);
- si->header_size = get_bits_count(gb);
- return 0;
-}
-
-static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
-{
- int t, mb_bits;
- int w = r->s.width, h = r->s.height;
- int i, mb_size;
-
- memset(si, 0, sizeof(SliceInfo));
- si->type = -1;
- if(get_bits1(gb))
- return -1;
- si->type = get_bits(gb, 2);
- if(si->type == 1) si->type = 0;
- si->quant = get_bits(gb, 5);
- if(get_bits(gb, 2))
- return -1;
- si->vlc_set = get_bits(gb, 2);
- get_bits1(gb);
- t = get_bits(gb, 13); /// ???
- if(!si->type || !get_bits1(gb))
- rv40_parse_picture_size(gb, &w, &h);
- si->width = w;
- si->height = h;
- mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
- for(i = 0; i < 5; i++)
- if(rv34_mb_max_sizes[i] > mb_size)
- break;
- mb_bits = rv34_mb_bits_sizes[i];
- si->start = get_bits(gb, mb_bits);
- si->header_size = get_bits_count(gb);
-
- return 0;
-}
-
-/**
- * Decode variable-length code constructed from variable-length codes
- * similar to Even-Rodeh and Elias Omega codes
- *
- * Code is constructed from bit chunks of even length (odd length means end of code)
- * and chunks are coded with variable-length codes too
- */
-int ff_rv34_get_omega(GetBitContext *gb)
-{
- int code = 1, t, tb;
-
- for(;;){
- t = get_vlc2(gb, omega_part_vlc.table, OMEGA_BITS, 1);
- tb = t >> 5;
- code = (code << tb) | (t & 0xF);
- if(t & 0x10) break;
- }
- return code;
-}
-
-/**
- * Decode signed integer variable-length code constructed from variable-length codes
- * similar to Even-Rodeh and Elias Omega codes
- *
- * Code is constructed from bit chunks of even length (odd length means end of code)
- * and chunks are coded with variable-length codes too
- */
-int ff_rv34_get_omega_signed(GetBitContext *gb)
-{
- int code;
-
- code = ff_rv34_get_omega(gb);
- if(code & 1)
- return -(code >> 1);
- else
- return code >> 1;
-}
-
-/**
- * Decode 4x4 intra types array
- */
-static int rv30_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int *dst)
-{
- int i, j, k;
- int A, B;
- int *ptr;
- int code;
-
- for(i = 0; i < 4; i++, dst += r->intra_types_stride){
- ptr = dst;
- for(j = 0; j < 4; j+= 2){
- code = (ff_rv34_get_omega(gb) - 1) << 1;
- if(code >= 81*2){
- av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n");
- return -1;
- }
- for(k = 0; k < 2; k++){
- A = ptr[-r->intra_types_stride] + 1;
- B = ptr[-1] + 1;
- *ptr++ = rv30_itype_from_context[A * 90 + B * 9 + rv30_itype_code[code + k]];
- if(ptr[-1] == 9){
- av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction mode\n");
- return -1;
- }
- }
- }
- }
- return 0;
-}
-
-/**
- * Decode 4x4 intra types array
- */
-static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int *dst)
-{
- MpegEncContext *s = &r->s;
- int i, j, k, v;
- int A, B, C;
- int pattern;
- int *ptr;
-
- for(i = 0; i < 4; i++, dst += r->intra_types_stride){
- if(!i && s->first_slice_line){
- pattern = get_vlc2(gb, aic_top_vlc.table, AIC_TOP_BITS, 1);
- dst[0] = (pattern >> 2) & 2;
- dst[1] = (pattern >> 1) & 2;
- dst[2] = pattern & 2;
- dst[3] = (pattern << 1) & 2;
- continue;
- }
- ptr = dst;
- for(j = 0; j < 4; j++){
- /* Coefficients are read using VLC chosen by prediction pattern
- * First one (used for retrieving a pair of coefficients) is
- * constructed from top, top right and left coefficients
- * Second one (used for retrieving only one coefficient) is
- * top + 10 * left
- */
- A = ptr[-r->intra_types_stride + 1]; // it won't be used for the last coefficient in a row
- B = ptr[-r->intra_types_stride];
- C = ptr[-1];
- pattern = A + (B << 4) + (C << 8);
- for(k = 0; k < MODE2_PATTERNS_NUM; k++)
- if(pattern == rv40_aic_table_index[k])
- break;
- if(j < 3 && k < MODE2_PATTERNS_NUM){ //pattern is found, decoding 2 coefficients
- v = get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2);
- *ptr++ = v/9;
- *ptr++ = v%9;
- j++;
- }else{
- if(B != -1 && C != -1)
- v = get_vlc2(gb, aic_mode1_vlc[B + C*10].table, AIC_MODE1_BITS, 1);
- else{ // tricky decoding
- v = 0;
- switch(C){
- case -1: // code 0 -> 1, 1 -> 0
- if(B == -1 || B == 0 || B == 1)
- v = get_bits1(gb) ^ 1;
- break;
- case 0:
- case 2: // code 0 -> 2, 1 -> 0
- v = (get_bits1(gb) ^ 1) << 1;
- break;
- }
- }
- *ptr++ = v;
- }
- }
- }
- return 0;
-}
-
-/**
- * Decode quantizer difference and return modified quantizer
- */
-static inline int rv34_decode_dquant(GetBitContext *gb, int quant)
-{
- if(get_bits1(gb))
- return av_clip(quant + rv34_dquant_tab[quant * 2 + get_bits1(gb)], 0, 31);
- else
- return get_bits(gb, 5);
-}
-
-/**
- * Decode macroblock information
- */
-static int rv30_decode_mb_info(RV34DecContext *r)
-{
- static const int rv30_p_types[6] = { RV34_MB_SKIP, RV34_MB_P_16x16, RV34_MB_P_8x8, -1, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 };
- static const int rv30_b_types[6] = { RV34_MB_SKIP, RV34_MB_B_INTERP, RV34_MB_B_FORWARD, RV34_MB_B_BACKWARD, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 };
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int code;
-
- code = ff_rv34_get_omega(gb) - 1;
- if(code > 11){
- av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n");
- return -1;
- }
- if(code > 5){
- av_log(s->avctx, AV_LOG_ERROR, "dquant needed\n");
- code -= 6;
- }
- if(s->pict_type != B_TYPE)
- return rv30_p_types[code];
- else
- return rv30_b_types[code];
-}
-
-/**
- * Decode macroblock information
- */
-static int rv40_decode_mb_info(RV34DecContext *r)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int q, i;
- int prev_type = 0;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int blocks[RV34_MB_TYPES];
- int count = 0;
-
- if(!r->s.mb_skip_run)
- r->s.mb_skip_run = ff_rv34_get_omega(gb);
-
- if(--r->s.mb_skip_run)
- return RV34_MB_SKIP;
-
- memset(blocks, 0, sizeof(blocks));
- if(r->avail[0])
- blocks[r->mb_type[mb_pos - 1]]++;
- if(r->avail[1])
- blocks[r->mb_type[mb_pos - s->mb_stride]]++;
- if(r->avail[1] && r->avail[2])
- blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++;
- if(r->avail[1] && r->avail[3])
- blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++;
-
- for(i = 0; i < RV34_MB_TYPES; i++){
- if(blocks[i] > count){
- count = blocks[i];
- prev_type = i;
- }
- }
- if(s->pict_type == P_TYPE){
- if(prev_type == RV34_MB_SKIP) prev_type = RV34_MB_P_16x16;
- prev_type = block_num_to_ptype_vlc_num[prev_type];
- q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1);
- if(q < PBTYPE_ESCAPE)
- return q;
- q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1);
- av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n");
- }else{
- prev_type = block_num_to_btype_vlc_num[prev_type];
- q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1);
- if(q < PBTYPE_ESCAPE)
- return q;
- q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1);
- av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n");
- }
- return 0;
-}
-
-/** @} */ //bitstream functions
-
-/**
- * @defgroup mv 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 };
-
-/**
- * Motion vectors prediction
- *
- * Motion prediction performed for the block by using median prediction of
- * motion vector from the left, top and right top blocks but in corener cases
- * some other vectors may be used instead
- */
-static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no)
-{
- MpegEncContext *s = &r->s;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
- int A[2], B[2], C[2];
- int no_A = 1, no_B = 1, no_C = 1;
- int i, j;
- int mx, my;
-
- memset(A, 0, sizeof(A));
- memset(B, 0, sizeof(B));
- memset(C, 0, sizeof(C));
- no_A = !r->avail[0];
- no_B = !r->avail[1];
- no_C = !r->avail[2];
- switch(block_type){
- case RV34_MB_P_16x16:
- case RV34_MB_P_MIX16x16:
- if(!no_C){
- 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];
- }
- break;
- case RV34_MB_P_8x8:
- mv_pos += (subblock_no & 1) + (subblock_no >> 1)*s->b8_stride;
- if(subblock_no & 1) no_A = 0;
- if(subblock_no & 2) no_B = 0;
- no_C |= (subblock_no == 3);
- if(subblock_no == 2) no_C = 0;
- if(!subblock_no) no_C = no_B;
- if(!no_C){
- 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];
- }
- if(subblock_no == 3){
- no_C = 0;
- 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];
- }
- break;
- case RV34_MB_P_16x8:
- mv_pos += subblock_no*s->b8_stride;
- no_B &= ~subblock_no;
- no_C |= subblock_no;
- if(!no_C){
- 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];
- }
- break;
- case RV34_MB_P_8x16:
- mv_pos += subblock_no;
- no_A &= ~subblock_no;
- if(!subblock_no) no_C = no_B;
- if(!no_C){
- 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];
- }
- break;
- default:
- no_A = no_B = no_C = 1;
- }
- if(!no_A){
- 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(!no_B){
- 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(no_C){
- if(no_B || (no_A && !r->rv30)){
- C[0] = A[0];
- C[1] = A[1];
- }else{
- 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];
- }
- }
- mx = mid_pred(A[0], B[0], C[0]);
- my = mid_pred(A[1], B[1], C[1]);
- mx += r->dmv[subblock_no][0];
- my += r->dmv[subblock_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;
- }
- }
-}
-
-/**
- * Predict motion vector for B-frame macroblock.
- */
-static inline void rv34_pred_b_vector(int A[2], int B[2], int C[2], int no_A, int no_B, int no_C, int *mx, int *my)
-{
- if(no_A + no_B + no_C){
- *mx = A[0] + B[0] + C[0];
- *my = A[1] + B[1] + C[1];
- if(no_A + no_B + no_C == 1){
- *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)
-{
- 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][2], B[2][2], C[2][2];
- int no_A[2], no_B[2], no_C[2];
- int c_mv_pos;
- int mx[2], my[2];
- int i, j;
-
- memset(A, 0, sizeof(A));
- memset(B, 0, sizeof(B));
- memset(C, 0, sizeof(C));
- memset(mx, 0, sizeof(mx));
- memset(my, 0, sizeof(my));
- if(!r->avail[0])
- no_A[0] = no_A[1] = 1;
- else{
- no_A[0] = no_A[1] = 0;
- if(r->mb_type[mb_pos - 1] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - 1] != RV34_MB_B_DIRECT)
- no_A[0] = 1;
- if(r->mb_type[mb_pos - 1] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - 1] != RV34_MB_B_DIRECT)
- no_A[1] = 1;
- if(!no_A[0]){
- A[0][0] = s->current_picture_ptr->motion_val[0][mv_pos - 1][0];
- A[0][1] = s->current_picture_ptr->motion_val[0][mv_pos - 1][1];
- }
- if(!no_A[1]){
- A[1][0] = s->current_picture_ptr->motion_val[1][mv_pos - 1][0];
- A[1][1] = s->current_picture_ptr->motion_val[1][mv_pos - 1][1];
- }
- }
- if(!r->avail[1]){
- no_B[0] = no_B[1] = 1;
- }else{
- no_B[0] = no_B[1] = 0;
- if(r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_DIRECT)
- no_B[0] = 1;
- if(r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_DIRECT)
- no_B[1] = 1;
- if(!no_B[0]){
- B[0][0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][0];
- B[0][1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][1];
- }
- if(!no_B[1]){
- B[1][0] = s->current_picture_ptr->motion_val[1][mv_pos - s->b8_stride][0];
- B[1][1] = s->current_picture_ptr->motion_val[1][mv_pos - s->b8_stride][1];
- }
- }
- if(r->avail[2]){
- no_C[0] = no_C[1] = 0;
- if(r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_DIRECT)
- no_C[0] = 1;
- if(r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_DIRECT)
- no_C[1] = 1;
- c_mv_pos = mv_pos - s->b8_stride + 2;
- }else if(r->avail[3]){
- no_C[0] = no_C[1] = 0;
- if(r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_DIRECT)
- no_C[0] = 1;
- if(r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_DIRECT)
- no_C[1] = 1;
- c_mv_pos = mv_pos - s->b8_stride - 1;
- }else{
- no_C[0] = no_C[1] = 1;
- c_mv_pos = 0;
- }
- if(!no_C[0]){
- C[0][0] = s->current_picture_ptr->motion_val[0][c_mv_pos][0];
- C[0][1] = s->current_picture_ptr->motion_val[0][c_mv_pos][1];
- }
- if(!no_C[1]){
- C[1][0] = s->current_picture_ptr->motion_val[1][c_mv_pos][0];
- C[1][1] = s->current_picture_ptr->motion_val[1][c_mv_pos][1];
- }
- switch(block_type){
- case RV34_MB_B_FORWARD:
- rv34_pred_b_vector(A[0], B[0], C[0], no_A[0], no_B[0], no_C[0], &mx[0], &my[0]);
- r->dmv[1][0] = 0;
- r->dmv[1][1] = 0;
- break;
- case RV34_MB_B_BACKWARD:
- r->dmv[1][0] = r->dmv[0][0];
- r->dmv[1][1] = r->dmv[0][1];
- r->dmv[0][0] = 0;
- r->dmv[0][1] = 0;
- rv34_pred_b_vector(A[1], B[1], C[1], no_A[1], no_B[1], no_C[1], &mx[1], &my[1]);
- break;
- case RV34_MB_B_DIRECT:
- rv34_pred_b_vector(A[0], B[0], C[0], no_A[0], no_B[0], no_C[0], &mx[0], &my[0]);
- rv34_pred_b_vector(A[1], B[1], C[1], no_A[1], no_B[1], no_C[1], &mx[1], &my[1]);
- break;
- default:
- no_A[0] = no_A[1] = no_B[0] = no_B[1] = no_C[0] = no_C[1] = 1;
- }
-
- mx[0] += r->dmv[0][0];
- my[0] += r->dmv[0][1];
- mx[1] += r->dmv[1][0];
- my[1] += r->dmv[1][1];
- for(j = 0; j < 2; j++){
- for(i = 0; i < 2; i++){
- s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx[0];
- s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my[0];
- s->current_picture_ptr->motion_val[1][mv_pos + i + j*s->b8_stride][0] = mx[1];
- s->current_picture_ptr->motion_val[1][mv_pos + i + j*s->b8_stride][1] = my[1];
- }
- }
-}
-
-/**
- * Generic motion compensation function - hopefully compiler will optimize it for each case
- *
- * @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
- */
-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)
-{
- MpegEncContext *s = &r->s;
- uint8_t *Y, *U, *V, *srcY, *srcU, *srcV;
- int dxy, mx, my, 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;
-
- mx = s->current_picture_ptr->motion_val[0][mv_pos][0];
- my = s->current_picture_ptr->motion_val[0][mv_pos][1];
- srcY = s->last_picture_ptr->data[0];
- srcU = s->last_picture_ptr->data[1];
- srcV = s->last_picture_ptr->data[2];
- src_x = s->mb_x * 16 + xoff + (mx >> 2);
- src_y = s->mb_y * 16 + yoff + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (xoff >> 1) + (mx >> 3);
- uvsrc_y = s->mb_y * 8 + (yoff >> 1) + (my >> 3);
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
- if( (unsigned)(src_x - !!(mx&3)*2) > s->h_edge_pos - !!(mx&3)*2 - (width <<3) - 3
- || (unsigned)(src_y - !!(my&3)*2) > s->v_edge_pos - !!(my&3)*2 - (height<<3) - 3){
- uint8_t *uvbuf= s->edge_emu_buffer + 20 * s->linesize;
-
- srcY -= 2 + 2*s->linesize;
- ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+4, (height<<3)+4,
- 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,
- 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,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- srcU = uvbuf;
- srcV = uvbuf + 16;
- }
- dxy = ((my & 3) << 2) | (mx & 3);
- uvmx = mx & 6;
- uvmy = my & 6;
- 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;
- if(block_type == RV34_MB_P_16x8){
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- Y += 8;
- srcY += 8;
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[0] (U, srcU, s->uvlinesize, 4, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[0] (V, srcV, s->uvlinesize, 4, uvmx, uvmy);
- }else if(block_type == RV34_MB_P_8x16){
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- Y += 8 * s->linesize;
- srcY += 8 * s->linesize;
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[1] (U, srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[1] (V, srcV, s->uvlinesize, 8, uvmx, uvmy);
- }else if(block_type == RV34_MB_P_8x8){
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[1] (U, srcU, s->uvlinesize, 4, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[1] (V, srcV, s->uvlinesize, 4, uvmx, uvmy);
- }else{
- s->dsp.put_h264_qpel_pixels_tab[0][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[0] (U, srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[0] (V, srcV, s->uvlinesize, 8, uvmx, uvmy);
- }
-}
-
-/**
- * B-frame specific motion compensation function
- *
- * @param r decoder context
- * @param block_type type of the current block
- */
-static inline void rv34_mc_b(RV34DecContext *r, const int block_type)
-{
- MpegEncContext *s = &r->s;
- uint8_t *srcY, *srcU, *srcV;
- int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
-
- if(block_type != RV34_MB_B_BACKWARD){
- mx = s->current_picture_ptr->motion_val[0][mv_pos][0];
- my = s->current_picture_ptr->motion_val[0][mv_pos][1];
- srcY = s->last_picture_ptr->data[0];
- srcU = s->last_picture_ptr->data[1];
- srcV = s->last_picture_ptr->data[2];
- }else{
- mx = s->current_picture_ptr->motion_val[1][mv_pos][0];
- my = s->current_picture_ptr->motion_val[1][mv_pos][1];
- srcY = s->next_picture_ptr->data[0];
- srcU = s->next_picture_ptr->data[1];
- srcV = s->next_picture_ptr->data[2];
- }
- if(block_type == RV34_MB_B_INTERP){
- mx += (s->next_picture_ptr->motion_val[0][mv_pos][0] + 1) >> 1;
- my += (s->next_picture_ptr->motion_val[0][mv_pos][1] + 1) >> 1;
- }
- src_x = s->mb_x * 16 + (mx >> 2);
- src_y = s->mb_y * 16 + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (mx >> 3);
- uvsrc_y = s->mb_y * 8 + (my >> 3);
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
- if( (unsigned)(src_x - !!(mx&3)*2) > s->h_edge_pos - !!(mx&3)*2 - 16 - 3
- || (unsigned)(src_y - !!(my&3)*2) > s->v_edge_pos - !!(my&3)*2 - 16 - 3){
- uint8_t *uvbuf= s->edge_emu_buffer + 20 * s->linesize;
-
- srcY -= 2 + 2*s->linesize;
- ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 16+4, 16+4,
- 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, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- srcU = uvbuf;
- srcV = uvbuf + 16;
- }
- dxy = ((my & 3) << 2) | (mx & 3);
- uvmx = mx & 6;
- uvmy = my & 6;
- s->dsp.put_h264_qpel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[0] (s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[0] (s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
-}
-
-/**
- * B-frame specific motion compensation function - for direct/interpolated blocks
- *
- * @param r decoder context
- * @param block_type type of the current block
- */
-static inline void rv34_mc_b_interp(RV34DecContext *r, const int block_type)
-{
- MpegEncContext *s = &r->s;
- uint8_t *srcY, *srcU, *srcV;
- int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
-
- mx = s->current_picture_ptr->motion_val[1][mv_pos][0];
- my = s->current_picture_ptr->motion_val[1][mv_pos][1];
- if(block_type == RV34_MB_B_INTERP){
- mx -= s->next_picture_ptr->motion_val[0][mv_pos][0] >> 1;
- my -= s->next_picture_ptr->motion_val[0][mv_pos][1] >> 1;
- }
- srcY = s->next_picture_ptr->data[0];
- srcU = s->next_picture_ptr->data[1];
- srcV = s->next_picture_ptr->data[2];
-
- src_x = s->mb_x * 16 + (mx >> 2);
- src_y = s->mb_y * 16 + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (mx >> 3);
- uvsrc_y = s->mb_y * 8 + (my >> 3);
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
- if( (unsigned)(src_x - !!(mx&3)*2) > s->h_edge_pos - !!(mx&3)*2 - 16 - 3
- || (unsigned)(src_y - !!(my&3)*2) > s->v_edge_pos - !!(my&3)*2 - 16 - 3){
- uint8_t *uvbuf= s->edge_emu_buffer + 20 * s->linesize;
-
- srcY -= 2 + 2*s->linesize;
- ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 16+4, 16+4,
- 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, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- srcU = uvbuf;
- srcV = uvbuf + 16;
- }
- dxy = ((my & 3) << 2) | (mx & 3);
- uvmx = mx & 6;
- uvmy = my & 6;
- s->dsp.avg_h264_qpel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize);
- s->dsp.avg_h264_chroma_pixels_tab[0] (s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.avg_h264_chroma_pixels_tab[0] (s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
-}
-
-/**
- * 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;
-
- switch(block_type){
- case RV34_MB_TYPE_INTRA:
- case RV34_MB_TYPE_INTRA16x16:
- for(j = 0; j < 2; j++){
- for(i = 0; i < 2; i++){
- s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + i + j*s->b8_stride][0] = 0;
- s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + i + j*s->b8_stride][1] = 0;
- }
- }
- return 0;
- case RV34_MB_SKIP:
- r->dmv[0][0] = 0;
- r->dmv[0][1] = 0;
- if(s->pict_type == P_TYPE){
- rv34_pred_mv(r, block_type, 0);
- rv34_mc(r, block_type, 0, 0, 0, 2, 2);
- break;
- }
- case RV34_MB_B_INTERP:
- r->dmv[0][0] = 0;
- r->dmv[0][1] = 0;
- r->dmv[1][0] = 0;
- r->dmv[1][1] = 0;
- rv34_pred_mv_b (r, RV34_MB_B_INTERP);
- rv34_mc_b (r, RV34_MB_B_INTERP);
- rv34_mc_b_interp(r, RV34_MB_B_INTERP);
- break;
- case RV34_MB_P_16x16:
- case RV34_MB_P_MIX16x16:
- r->dmv[0][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[0][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv(r, block_type, 0);
- rv34_mc(r, block_type, 0, 0, 0, 2, 2);
- break;
- case RV34_MB_B_FORWARD:
- case RV34_MB_B_BACKWARD:
- r->dmv[0][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[0][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv_b (r, block_type);
- rv34_mc_b (r, block_type);
- break;
- case RV34_MB_P_16x8:
- case RV34_MB_P_8x16:
- case RV34_MB_B_DIRECT:
- r->dmv[0][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[0][1] = ff_rv34_get_omega_signed(gb);
- r->dmv[1][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[1][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv(r, block_type, 0);
- rv34_pred_mv(r, block_type, 1);
- if(block_type == RV34_MB_P_16x8){
- rv34_mc(r, block_type, 0, 0, 0, 2, 1);
- rv34_mc(r, block_type, 0, 8, s->b8_stride, 2, 1);
- }
- if(block_type == RV34_MB_P_8x16){
- rv34_mc(r, block_type, 0, 0, 0, 1, 2);
- rv34_mc(r, block_type, 8, 0, 1, 1, 2);
- }
- if(block_type == RV34_MB_B_DIRECT){
- rv34_pred_mv_b (r, block_type);
- rv34_mc_b (r, block_type);
- rv34_mc_b_interp(r, block_type);
- }
- break;
- case RV34_MB_P_8x8:
- for(i=0;i< 4;i++){
- r->dmv[i][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[i][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv(r, block_type, i);
- rv34_mc(r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1);
- }
- break;
- }
-
- return 0;
-}
-/** @} */ // mv group
-
-/**
- * @defgroup recons Macroblock reconstruction functions
- * @{
- */
-/** Mapping of RV40 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 RV40 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 no_up, int no_left, int no_down, int no_right)
-{
- uint8_t *prev = dst - stride + 4;
- uint32_t topleft;
-
- if(no_up && no_left)
- itype = DC_128_PRED;
- else if(no_up){
- if(itype == VERT_PRED) itype = HOR_PRED;
- if(itype == DC_PRED) itype = LEFT_DC_PRED;
- }else if(no_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(no_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(no_right && !no_up){
- topleft = dst[-stride + 3] * 0x01010101;
- prev = &topleft;
- }
- r->h.pred4x4[itype](dst, prev, stride);
-}
-
-/** add_pixels_clamped for 4x4 block */
-static void rv34_add_4x4_block(uint8_t *dst, int stride, DCTELEM block[64], int off)
-{
- int x, y;
- for(y = 0; y < 4; y++)
- for(x = 0; x < 4; x++)
- dst[x + y*stride] = av_clip_uint8(dst[x + y*stride] + block[off + x+y*8]);
-}
-
-static void rv34_output_macroblock(RV34DecContext *r, int *intra_types, int cbp, int is16)
-{
- MpegEncContext *s = &r->s;
- DSPContext *dsp = &s->dsp;
- int i, j;
- uint8_t *Y, *YY, *U, *V;
- int no_up, no_left, no_topright, itype;
-
- no_up = !r->avail[1];
- Y = s->dest[0];
- U = s->dest[1];
- V = s->dest[2];
- if(!is16){
- for(j = 0; j < 4; j++){
- no_left = !r->avail[0];
- YY = Y;
- for(i = 0; i < 4; i++, cbp >>= 1, YY += 4){
- no_topright = no_up || (i==3 && j) || (i==3 && !j && (s->mb_x-1) == s->mb_width);
- rv34_pred_4x4_block(r, YY, s->linesize, ittrans[intra_types[i]], no_up, no_left, i || (j==3), no_topright);
- no_left = 0;
- if(!(cbp & 1)) continue;
- rv34_add_4x4_block(YY, s->linesize, s->block[(i>>1)+(j&2)], (i&1)*4+(j&1)*32);
- }
- no_up = 0;
- Y += s->linesize * 4;
- intra_types += r->intra_types_stride;
- }
- intra_types -= r->intra_types_stride * 4;
- no_up = !r->avail[1];
- for(j = 0; j < 2; j++){
- no_left = !r->avail[0];
- for(i = 0; i < 2; i++, cbp >>= 1, no_left = 0){
- no_topright = no_up || (i && j) || (i && !j && (s->mb_x-1) == s->mb_width);
- 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]], no_up, no_left, i || j, no_topright);
- 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]], no_up, no_left, i || j, no_topright);
- if(cbp & 0x01)
- rv34_add_4x4_block(U + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[4], i*4+j*32);
- if(cbp & 0x10)
- rv34_add_4x4_block(V + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[5], i*4+j*32);
- }
- no_up = 0;
- }
- }else{
- no_left = !r->avail[0];
- itype = ittrans16[intra_types[0]];
- if(no_up && no_left)
- itype = DC_128_PRED8x8;
- else if(no_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(no_left){
- if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8;
- if(itype == HOR_PRED8x8) itype = VERT_PRED8x8;
- if(itype == DC_PRED8x8) itype = TOP_DC_PRED8x8;
- }
- r->h.pred16x16[itype](Y, s->linesize);
- dsp->add_pixels_clamped(s->block[0], Y, s->current_picture.linesize[0]);
- dsp->add_pixels_clamped(s->block[1], Y + 8, s->current_picture.linesize[0]);
- Y += s->current_picture.linesize[0] * 8;
- dsp->add_pixels_clamped(s->block[2], Y, s->current_picture.linesize[0]);
- dsp->add_pixels_clamped(s->block[3], Y + 8, s->current_picture.linesize[0]);
-
- itype = ittrans16[intra_types[0]];
- if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
- if(no_up && no_left)
- itype = DC_128_PRED8x8;
- else if(no_up){
- if(itype == VERT_PRED8x8) itype = HOR_PRED8x8;
- if(itype == DC_PRED8x8) itype = LEFT_DC_PRED8x8;
- }else if(no_left){
- if(itype == HOR_PRED8x8) itype = VERT_PRED8x8;
- if(itype == DC_PRED8x8) itype = TOP_DC_PRED8x8;
- }
- r->h.pred8x8[itype](U, s->uvlinesize);
- dsp->add_pixels_clamped(s->block[4], U, s->uvlinesize);
- r->h.pred8x8[itype](V, s->uvlinesize);
- dsp->add_pixels_clamped(s->block[5], V, s->uvlinesize);
- }
-}
-
-/** @} */ // recons group
-
-/**
- * @addtogroup bitstream
- * Decode macroblock header and return CBP in case of success, -1 otherwise.
- */
-static int rv34_decode_mb_header(RV34DecContext *r, int *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->rv30){
- r->is16 = 0;
- switch(decode210(gb)){
- case 0: // 16x16 block
- r->is16 = 1;
- break;
- case 1:
- break;
- case 2:
- av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
- // q = decode_dquant(gb);
- break;
- }
- 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 if(!r->si.type && r->rv30){
- r->is16 = get_bits1(gb);
- 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 == P_TYPE)
- r->mb_type[mb_pos] = RV34_MB_P_16x16;
- if(s->pict_type == B_TYPE)
- r->mb_type[mb_pos] = RV34_MB_B_INTERP;
- }
- 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){
- for(i = 0; i < 16; i++)
- intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 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){
- if(r->decode_intra_types(r, gb, intra_types) < 0)
- return -1;
- r->chroma_vlc = 0;
- r->luma_vlc = 1;
- }else{
- t = get_bits(gb, 2);
- for(i = 0; i < 16; i++)
- intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = t;
- r->chroma_vlc = 0;
- r->luma_vlc = 2;
- }
- 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);
-}
-
/**
- * @addtogroup recons
- * @{
- */
-/** Mask for retrieving all bits in coded block pattern
- * corresponding to one 8x8 block.
- */
-#define LUMA_CBP_BLOCK_MASK 0x303
-
-#define U_CBP_MASK 0x0F0000
-#define V_CBP_MASK 0xF00000
-
-
-static void rv34_apply_differences(RV34DecContext *r, int cbp)
-{
- static const int shifts[4] = { 0, 2, 8, 10 };
- MpegEncContext *s = &r->s;
- int i;
-
- for(i = 0; i < 4; i++)
- if(cbp & (LUMA_CBP_BLOCK_MASK << shifts[i]))
- s->dsp.add_pixels_clamped(s->block[i], s->dest[0] + (i & 1)*8 + (i&2)*4*s->linesize, s->linesize);
- if(cbp & U_CBP_MASK)
- s->dsp.add_pixels_clamped(s->block[4], s->dest[1], s->uvlinesize);
- if(cbp & V_CBP_MASK)
- s->dsp.add_pixels_clamped(s->block[5], s->dest[2], s->uvlinesize);
-}
-
-static int rv34_decode_macroblock(RV34DecContext *r, int *intra_types)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int cbp, cbp2;
- int i, blknum, blkoff;
- DCTELEM block16[64];
- int luma_dc_quant;
-
- // calculate which neighbours are available
- memset(r->avail, 0, sizeof(r->avail));
- if(s->mb_x && !(s->first_slice_line && s->mb_x == s->resync_mb_x))
- r->avail[0] = 1;
- if(!s->first_slice_line)
- r->avail[1] = 1;
- if((s->mb_x+1) < s->mb_width && (!s->first_slice_line || (s->first_slice_line && (s->mb_x+1) == s->resync_mb_x)))
- r->avail[2] = 1;
- if(s->mb_x && !s->first_slice_line && !((s->mb_y-1)==s->resync_mb_y && s->mb_x == s->resync_mb_x))
- r->avail[3] = 1;
-
- s->qscale = r->si.quant;
- cbp = cbp2 = rv34_decode_mb_header(r, intra_types);
-
- if(cbp == -1)
- return -1;
-
- luma_dc_quant = r->si.type ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale];
- if(r->is16){
- memset(block16, 0, sizeof(block16));
- rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0);
- rv34_dequant4x4_16x16(block16, 0, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
- rv34_intra_inv_transform_noround(block16, 0);
- }
-
- for(i = 0; i < 16; i++, cbp >>= 1){
- if(!r->is16 && !(cbp & 1)) continue;
- blknum = ((i & 2) >> 1) + ((i & 8) >> 2);
- blkoff = ((i & 1) << 2) + ((i & 4) << 3);
- if(cbp & 1)
- rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0);
- if((cbp & 1) || r->is16){
- rv34_dequant4x4(s->block[blknum], blkoff, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
- if(r->is16) //FIXME: optimize
- s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)];
- rv34_intra_inv_transform(s->block[blknum], blkoff);
- }
- }
- if(r->block_type == RV34_MB_P_MIX16x16)
- r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
- for(; i < 24; i++, cbp >>= 1){
- if(!(cbp & 1)) continue;
- blknum = ((i & 4) >> 2) + 4;
- blkoff = ((i & 1) << 2) + ((i & 2) << 4);
- rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1);
- rv34_dequant4x4(s->block[blknum], blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]);
- rv34_intra_inv_transform(s->block[blknum], blkoff);
- }
- if(IS_INTRA(s->current_picture_ptr->mb_type[s->mb_x + s->mb_y*s->mb_stride]))
- rv34_output_macroblock(r, intra_types, cbp2, r->is16);
- else
- rv34_apply_differences(r, cbp2);
-
- return 0;
-}
-
-static int check_slice_end(RV34DecContext *r, MpegEncContext *s)
-{
- int bits;
- if(r->s.mb_skip_run > 1)
- return 0;
- if(s->mb_y >= s->mb_height)
- return 1;
- bits = r->bits - get_bits_count(&s->gb);
- if(bits < 0 || (bits < 8 && !show_bits(&s->gb, bits)))
- return 1;
- return 0;
-}
-
-static inline int slice_compare(SliceInfo *si1, SliceInfo *si2)
-{
- return si1->type != si2->type ||
- si1->start >= si2->start ||
- si1->width != si2->width ||
- si1->height != si2->height;
-}
-
-static int rv34_decode_slice(RV34DecContext *r, int size, int end, int *last)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int mb_pos;
- int res;
- int old_mb_x = r->ssi.mb_x, old_mb_y = r->ssi.mb_y;
- *last = 1;
-
- init_get_bits(&r->s.gb, r->slice_data, r->si.size);
- res = r->parse_slice_header(r, gb, &r->si);
- if((res < 0 && !s->current_picture_ptr) || (r->prev_si.type == -1 && r->si.start)){
- av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n");
- *last = 0;
- return -1;
- }
- if(res < 0 || (r->prev_si.type != -1 && slice_compare(&r->prev_si, &r->si))){
- r->ssi.data = av_realloc(r->ssi.data, r->ssi.data_size + (size>>3));
- memcpy(r->ssi.data + r->ssi.data_size, r->slice_data, size >> 3);
- r->ssi.data_size += size >> 3; // XXX: overflow check?
- size = r->ssi.data_size * 8;
- init_get_bits(&r->s.gb, r->ssi.data, r->ssi.data_size * 8);
- r->si = r->prev_si;
- skip_bits(gb, r->ssi.bits_used);
- s->mb_x = r->ssi.mb_x;
- s->mb_y = r->ssi.mb_y;
- r->si.start = s->mb_x + s->mb_y * s->mb_width;
- r->truncated = 1;
- }
-
- if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
- if(s->width != r->si.width || s->height != r->si.height /*&& avcodec_check_dimensions(s->avctx, r->si.width, r->si.height) >= 0 */){
- av_log(s->avctx, AV_LOG_DEBUG, "Changing dimensions to %dx%d\n", r->si.width,r->si.height);
- MPV_common_end(s);
- s->width = r->si.width;
- s->height = r->si.height;
- if(MPV_common_init(s) < 0)
- return -1;
- }
- s->pict_type = r->si.type ? r->si.type : I_TYPE;
- if(MPV_frame_start(s, s->avctx) < 0)
- return -1;
- ff_er_frame_start(s);
- s->current_picture_ptr = &s->current_picture;
- s->mb_x = s->mb_y = 0;
- r->truncated = 0;
- }
-
- r->si.size = size;
- r->si.end = end;
- s->qscale = r->si.quant;
- r->bits = r->si.size;
- r->block_start = r->si.start;
- s->mb_num_left = r->si.end - r->si.start;
- r->s.mb_skip_run = 0;
-
- r->prev_si = r->si;
-
- mb_pos = s->mb_x + s->mb_y * s->mb_width;
- if(!r->truncated && r->block_start != mb_pos){
- av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->block_start, mb_pos);
- s->mb_x = r->block_start % s->mb_width;
- s->mb_y = r->block_start / s->mb_width;
- }
- if(!r->truncated){
- memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(int));
- 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) && s->mb_num_left-- && s->mb_y < s->mb_height) {
- ff_update_block_index(s);
- s->dsp.clear_blocks(s->block[0]);
-
- /* save information about decoded position in case of truncated slice */
- if(r->bits > get_bits_count(gb)){
- r->ssi.bits_used = get_bits_count(gb);
- r->ssi.mb_x = s->mb_x;
- r->ssi.mb_y = s->mb_y;
- }
-
- if(rv34_decode_macroblock(r, r->intra_types + (s->mb_x + 1) * 4) < 0)
- break;
- 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(int));
- memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(int));
- }
- if(s->mb_x == s->resync_mb_x)
- s->first_slice_line=0;
- }
- if(!r->truncated)
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
- else // add only additionally decoded blocks
- ff_er_add_slice(s, old_mb_x+1, old_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
- r->truncated = 0;
- *last = 0;
- if(s->mb_y >= s->mb_height)
- *last = 1;
- if(r->bits > get_bits_count(gb) && show_bits(gb, r->bits-get_bits_count(gb)))
- *last = 1;
-
- r->ssi.data = av_realloc(r->ssi.data, r->bits >> 3);
- r->ssi.data_size = r->bits >> 3;
- memcpy(r->ssi.data, r->slice_data, r->bits >> 3);
- return 0;
-}
-
-#define CLIP_SYMM(a, b) av_clip(a, -(b), b)
-/**
- * Weaker deblocking
- */
-static inline void rv34_weak_loop_filter(uint8_t *src, const int step,
- const int flag0, const int flag1, const int mult,
- const int lim0, const int lim1, const int lim2, const int thr1,
- const int S0, const int S1, const int S2, const int S3)
-{
- uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
- int t, diff;
-
- t = src[0*step] - src[-1*step];
- if(!t) return;
- t = (mult * FFABS(t)) >> 7;
- if(t > 3) return;
- if(flag0 && flag1 && t > 2) return;
- t = src[-1*step] - src[0*step];
-
- if(flag0 && flag1)
- diff = (src[-2*step] - src[1*step] + t*4 + 4) >> 3;
- else
- diff = (t + 1) >> 1;
- diff = CLIP_SYMM(diff, lim2);
- src[-1*step] = cm[src[-1*step] + diff];
- src[ 0*step] = cm[src[ 0*step] - diff];
- if(FFABS(S1) <= thr1 && flag0){
- t = (S0 + S1 - diff) >> 1;
- src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim1)];
- }
- if(FFABS(S3) <= thr1 && flag1){
- t = (S2 + S3 + diff) >> 1;
- src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim0)];
- }
-}
-
-/**
- * This macro is used for calculating 25*x0+26*x1+26*x2+26*x3+25*x4
- * or 25*x0+26*x1+51*x2+26*x3
- * parameter sub - index of the value with coefficient = 25
- * parameter last - index of the value with coefficient 25 or 51
- */
-#define RV34_STRONG_FILTER(src, step, start, last, sub) \
- 26*(src[start*step] + src[(start+1)*step] + src[(start+2)*step] + src[(start+3)*step] + src[last*step]) - src[last*step] - src[sub*step]
-/**
- * Deblocking filter, the alternated version from JVT-A003r1 H.26L draft.
- */
-static inline void rv34_adaptive_loop_filter(uint8_t *src, const int step, const int stride, const int dmode, const int lim0, const int lim1, const int mult, const int thr0, const int thr1, const int chroma, const int edge)
-{
- int diffs[4][4];
- int s0 = 0, s1 = 0, s2 = 0, s3 = 0;
- uint8_t *ptr;
- int flag0 = 1, flag1 = 1;
- int llim0 = 3, llim1 = 3;
- int i, t, sflag;
- int p0, p1;
- int v88;
-
- for(i = 0, ptr = src; i < 4; i++, ptr += stride){
- diffs[i][0] = ptr[-2*step] - ptr[-1*step];
- diffs[i][1] = ptr[-2*step] - ptr[-3*step];
- diffs[i][2] = ptr[ 1*step] - ptr[ 0*step];
- diffs[i][3] = ptr[ 1*step] - ptr[ 2*step];
- s0 += diffs[i][0];
- s1 += diffs[i][1];
- s2 += diffs[i][2];
- s3 += diffs[i][3];
- }
- if(FFABS(s0) >= (thr0<<2)){
- llim0 = 1;
- flag0 = 0;
- }
- if(FFABS(s2) >= (thr0<<2)){
- llim1 = 1;
- flag1 = 0;
- }
- if(llim0 + llim1 == 2)
- return;
-
- if(!edge)
- flag0 = flag1 = 0;
- if(flag0 && FFABS(s1) >= thr1)
- flag0 = 0;
- if(flag1 && FFABS(s3) >= thr1)
- flag1 = 0;
-
- v88 = (lim0 + lim1 + llim0 + llim1) >> 1;
- if(flag0 + flag1 == 2){ /* strong filtering */
- for(i = 0; i < 4; i++, src += stride){
- t = src[0*step] - src[-1*step];
- if(!t) continue;
- sflag = (mult * FFABS(t)) >> 7;
- if(sflag > 1) continue;
-
- p0 = (RV34_STRONG_FILTER(src, step, -3, 1, -3) + rv34_dither_l[dmode + i]) >> 7;
- p1 = (RV34_STRONG_FILTER(src, step, -1, 3, -1) + rv34_dither_r[dmode + i]) >> 7;
- if(!sflag){
- src[-1*step] = p0;
- src[ 0*step] = p1;
- }else{
- if((src[-1*step] - p0) >= -v88 && (src[-1*step] - p0) <= v88)
- src[-1*step] = p0;
- else
- src[-1*step] = p1;
- if((src[ 0*step] - p1) >= -v88 && (src[ 0*step] - p1) <= v88)
- src[ 0*step] = p1;
- else
- src[ 0*step] = src[-1*step];
- }
- p0 = (RV34_STRONG_FILTER(src, step, -4, 0, -4) + rv34_dither_l[dmode + i]) >> 7;
- p1 = (RV34_STRONG_FILTER(src, step, -1, 3, -1) + rv34_dither_r[dmode + i]) >> 7;
- if(!sflag){
- src[-2*step] = p0;
- src[ 1*step] = p1;
- }else{
- if((src[-2*step] - p0) >= -v88 && (src[-2*step] - p0) <= v88)
- src[-2*step] = p0;
- else
- src[-2*step] += v88;
- if((src[ 1*step] - p1) >= -v88 && (src[ 1*step] - p1) <= v88)
- src[ 1*step] = p1;
- else
- src[ 1*step] += v88;
- }
- if(!chroma){
- src[-3*step] = (RV34_STRONG_FILTER(src, step, -4, -1, -3) + 64) >> 7;
- src[ 2*step] = (RV34_STRONG_FILTER(src, step, 0, 0, 2) + 64) >> 7;
- }
- }
- }else if(llim0 == 3 && llim1 == 3)
- for(i = 0; i < 4; i++, src += stride)
- rv34_weak_loop_filter(src, step, 1, 1, mult, lim0, lim1, v88, thr1,
- diffs[i][0], diffs[i][1], diffs[i][2], diffs[i][3]);
- else
- for(i = 0; i < 4; i++, src += stride)
- rv34_weak_loop_filter(src, step, llim0==3, llim1==3, mult, lim0>>1, lim1>>1, v88>>1, thr1,
- diffs[i][0], diffs[i][1], diffs[i][2], diffs[i][3]);
-}
-
-static void rv34_v_loop_filter(uint8_t *src, int stride, int dmode, int lim0, int lim1, int mult, int thr0, int thr1, int chroma, int edge){
- rv34_adaptive_loop_filter(src, 1, stride, dmode, lim0, lim1, mult, thr0, thr1, chroma, edge);
-}
-static void rv34_h_loop_filter(uint8_t *src, int stride, int dmode, int lim0, int lim1, int mult, int thr0, int thr1, int chroma, int edge){
- rv34_adaptive_loop_filter(src, stride, 1, dmode, lim0, lim1, mult, thr0, thr1, chroma, edge);
-}
-
-static void rv34_loop_filter(RV34DecContext *r)
-{
- MpegEncContext *s = &r->s;
- int mb_pos;
- int i, j;
- int no_up, no_left;
- uint8_t *Y, *U, *V;
- const int alpha = rv34_alpha_tab[s->qscale], beta = rv34_beta_tab[s->qscale];
- //XXX these are probably not correct
- const int thr = s->qscale, lim0 = rv34_filter_clip_tbl[1][s->qscale], lim1 = rv34_filter_clip_tbl[2][s->qscale];
-
- mb_pos = s->resync_mb_x + s->resync_mb_y * s->mb_stride;
- memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(int));
- s->first_slice_line = 1;
- s->mb_x= s->resync_mb_x;
- s->mb_y= s->resync_mb_y;
- ff_init_block_index(s);
- while(s->mb_num_left-- && s->mb_y < s->mb_height) {
- ff_update_block_index(s);
- if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
- no_up = s->first_slice_line || !IS_INTRA(s->current_picture_ptr->mb_type[mb_pos - s->mb_stride]);
- no_left = !s->mb_x || (s->first_slice_line && s->mb_x == s->resync_mb_x) || !IS_INTRA(s->current_picture_ptr->mb_type[mb_pos - 1]);
- for(j = 0; j < 4; j++){
- for(i = 0; i < 4; i++){
- Y = s->dest[0] + i*4 + j*4*s->linesize;
- if(!j && !no_up)
- rv34_h_loop_filter(Y, s->linesize, i*4+j, lim0, lim1, alpha, beta, thr, 0, 1);
- if(j != 3)
- rv34_h_loop_filter(Y + 4*s->linesize, s->linesize, i*4+j, lim0, lim1, alpha, beta, thr, 0, 0);
- if(i || !no_left)
- rv34_v_loop_filter(Y, s->linesize, i*4+j, lim0, lim1, alpha, beta, thr, 0, !i);
- }
- }
- }
- if (++s->mb_x == s->mb_width) {
- s->mb_x = 0;
- s->mb_y++;
- ff_init_block_index(s);
- mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- }
- if(s->mb_x == s->resync_mb_x)
- s->first_slice_line=0;
- }
-
-}
-/** @} */ // recons group end
-
-/**
- * Initialize decoder
- * @todo Maybe redone in some other way
+ * Common decoding functions
*/
-static int rv34_decode_init(AVCodecContext *avctx)
-{
- RV34DecContext *r = avctx->priv_data;
- MpegEncContext *s = &r->s;
-
- static int tables_done = 0;
-
- r->rv30 = (avctx->codec_id == CODEC_ID_RV30);
- 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 = PIX_FMT_YUV420P;
- avctx->has_b_frames = 1;
- s->low_delay = 0;
-
- if (MPV_common_init(s) < 0)
- return -1;
-
- ff_h264_pred_init(&r->h, CODEC_ID_RV40);
-
- r->intra_types_stride = (s->mb_width + 1) * 4;
- r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(int));
- 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(int));
-
- if(!tables_done){
- rv34_init_tables();
- tables_done = 1;
- }
- r->prev_si.type = -1;
- if(r->rv30){
- if(avctx->extradata_size < 2){
- av_log(avctx, AV_LOG_ERROR, "Extradata is too small\n");
- return -1;
- }
- r->rpr = (avctx->extradata[1] & 7) >> 1;
- r->rpr = FFMIN(r->rpr + 1, 3);
- }
- r->parse_slice_header = r->rv30 ? rv30_parse_slice_header : rv40_parse_slice_header;
- r->decode_intra_types = r->rv30 ? rv30_decode_intra_types : rv40_decode_intra_types;
- r->decode_mb_info = r->rv30 ? rv30_decode_mb_info : rv40_decode_mb_info;
- if(r->rv30){
- r->luma_dc_quant_i = rv30_luma_dc_quant;
- r->luma_dc_quant_p = rv30_luma_dc_quant;
- }else{
- r->luma_dc_quant_i = rv40_luma_quant[0];
- r->luma_dc_quant_p = rv40_luma_quant[1];
- }
- return 0;
-}
-
-static int rv34_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- uint8_t *buf, int buf_size)
-{
- RV34DecContext *r = avctx->priv_data;
- MpegEncContext *s = &r->s;
- AVFrame *pict = data;
- SliceInfo si;
- int i;
- int slice_count, *slice_offset;
- int zero_offset = {0};
- int last = 0;
-
- /* no supplementary picture */
- if (buf_size == 0) {
- /* special case for last picture */
- if (s->low_delay==0 && s->next_picture_ptr) {
- *pict= *(AVFrame*)s->next_picture_ptr;
- s->next_picture_ptr= NULL;
-
- *data_size = sizeof(AVFrame);
- }
- }
-
- if(avctx->slice_count){
- slice_count = avctx->slice_count;
- slice_offset = avctx->slice_offset;
- }else{
- slice_count = 1;
- slice_offset = &zero_offset;
- }
-
- for(i=0; i<slice_count; i++){
- int offset= slice_offset[i];
- int size;
-
- if(i+1 == slice_count)
- size= buf_size - offset;
- else
- size= slice_offset[i+1] - offset;
-
- r->si.size = size * 8;
- r->si.end = s->mb_width * s->mb_height;
- if(i+1 < slice_count){
- init_get_bits(&s->gb, buf+slice_offset[i+1], (buf_size-slice_offset[i+1])*8);
- if(r->parse_slice_header(r, &r->s.gb, &si) < 0){
- if(i+2 < slice_count)
- size = slice_offset[i+2] - offset;
- else
- size = buf_size - offset;
- r->si.size = size * 8;
- }else
- r->si.end = si.start;
- }
- r->slice_data = buf + offset;
- rv34_decode_slice(r, r->si.size, r->si.end, &last);
- if(last)
- break;
- s->mb_num_left = r->si.end - r->si.start;
- //rv40_postprocess(r);
- }
-
- if(last){
- r->prev_si.type = -1;
- ff_er_frame_end(s);
- MPV_frame_end(s);
- if (s->pict_type == B_TYPE || s->low_delay) {
- *pict= *(AVFrame*)s->current_picture_ptr;
- } else if (s->last_picture_ptr != NULL) {
- *pict= *(AVFrame*)s->last_picture_ptr;
- }
-
- if(s->last_picture_ptr || s->low_delay){
- *data_size = sizeof(AVFrame);
- ff_print_debug_info(s, pict);
- }
- s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
- }
- return buf_size;
-}
-
-static int rv34_decode_end(AVCodecContext *avctx)
-{
- RV34DecContext *r = avctx->priv_data;
-
- MPV_common_end(&r->s);
-
- av_freep(&r->intra_types_hist);
- r->intra_types = NULL;
- av_freep(&r->mb_type);
- av_freep(&r->ssi.data);
-
- return 0;
-}
-
-AVCodec rv30_decoder = {
- "rv30",
- CODEC_TYPE_VIDEO,
- CODEC_ID_RV30,
- sizeof(RV34DecContext),
- rv34_decode_init,
- NULL,
- rv34_decode_end,
- rv34_decode_frame,
-};
-
-AVCodec rv40_decoder = {
- "rv40",
- CODEC_TYPE_VIDEO,
- CODEC_ID_RV40,
- sizeof(RV34DecContext),
- rv34_decode_init,
- NULL,
- rv34_decode_end,
- rv34_decode_frame,
-};
+int ff_rv34_get_start_offset(GetBitContext *gb, int blocks);
+int ff_rv34_get_omega(GetBitContext *gb);
+int ff_rv34_decode_init(AVCodecContext *avctx);
+int ff_rv34_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size);
+int ff_rv34_decode_end(AVCodecContext *avctx);
+/** @} */
+#endif /* RV34_H */
Copied: rv40/rv34data.h (from r1371, /rv40/rv40data.h)
==============================================================================
--- /rv40/rv40data.h (original)
+++ rv40/rv34data.h Wed Sep 19 18:55:05 2007
@@ -20,12 +20,12 @@
*/
/**
- * @file rv40data.h
- * Miscellaneous RV40 tables.
+ * @file rv34data.h
+ * Miscellaneous RV30/40 tables.
*/
-#ifndef RV40DATA_H
-#define RV40DATA_H
+#ifndef RV34DATA_H
+#define RV34DATA_H
#include <stdint.h>
@@ -45,15 +45,6 @@ static const uint8_t rv34_cbp_code[16] =
};
/**
- * Standard widths and heights coded in RV40
- */
-//@{
-static const int rv40_standard_widths[] = { 160, 172, 240, 320, 352, 640, 704, 0};
-static const int rv40_standard_heights[] = { 120, 132, 144, 240, 288, 480, 0, 0};
-static const int rv40_standard_heights2[] = { 180, 360, 576, 0};
-//@}
-
-/**
* Precalculated results of division by three and modulo three for values 0-107
*
* A lot of four-tuples in RV40 are represented as c0*27+c1*9+c2*3+c3
@@ -89,33 +80,6 @@ static const uint8_t modulo_three_table[
{ 3, 2, 1, 2 }, { 3, 2, 2, 0 }, { 3, 2, 2, 1 }, { 3, 2, 2, 2 },
};
-#define MODE2_PATTERNS_NUM 20
-/**
- * Intra types table
- *
- * These values are actually coded 3-tuples
- * used for detecting standard block configurations
- */
-static const uint16_t rv40_aic_table_index[MODE2_PATTERNS_NUM] = {
- 0x000, 0x100, 0x200,
- 0x011, 0x111, 0x211, 0x511, 0x611,
- 0x022, 0x122, 0x222, 0x722,
- 0x272, 0x227,
- 0x822, 0x282, 0x228,
- 0x112, 0x116, 0x221
-};
-
-/**
- * Luma quantizer values
- * Second table is used for inter blocks
- */
-static const uint8_t rv40_luma_quant[2][32] = {
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 22, 22, 22, 22 },
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 20, 21, 21, 22, 23, 23, 23, 24, 24, 24, 24 }
-};
-
/**
* Chroma quantizer values
* Second table is used for DC-only blocks
@@ -226,4 +190,4 @@ static const uint8_t rv34_filter_clip_tb
}
};
/** @} */ // end loopfilter group
-#endif /* RV40DATA_H */
+#endif /* RV34DATA_H */
Modified: rv40/rv40.c
==============================================================================
--- rv40/rv40.c (original)
+++ rv40/rv40.c Wed Sep 19 18:55:05 2007
@@ -1,6 +1,6 @@
/*
* RV40 decoder
- * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
+ * Copyright (c) 2007 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
@@ -21,205 +21,27 @@
/**
* @file rv40.c
- * RV30 and RV40 decoder.
+ * RV40 decoder.
*/
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
-#include "rv40vlc.h"
+#include "rv34.h"
#include "rv40vlc2.h"
#include "rv40data.h"
-#include "rv30data.h"
-
-#include "h264pred.h"
-
-//#define DEBUG
-/** Translation of RV40 macroblock types to lavc ones */
-static const int rv34_mb_type_to_lavc[12] = {
- MB_TYPE_INTRA, MB_TYPE_INTRA16x16, MB_TYPE_16x16, MB_TYPE_8x8,
- MB_TYPE_16x16, MB_TYPE_16x16, MB_TYPE_SKIP, MB_TYPE_DIRECT2,
- MB_TYPE_16x8, MB_TYPE_8x16, MB_TYPE_DIRECT2, MB_TYPE_16x16
-};
-
-/**
- * RV30 and RV40 Macroblock types
- * @{
- */
-enum RV40BlockTypes{
- RV34_MB_TYPE_INTRA, ///< Intra macroblock
- RV34_MB_TYPE_INTRA16x16, ///< Intra macroblock with DCs in a separate 4x4 block
- RV34_MB_P_16x16, ///< P-frame macroblock, one motion frame
- RV34_MB_P_8x8, ///< P-frame macroblock, 8x8 motion compensation partitions
- RV34_MB_B_FORWARD, ///< B-frame macroblock, forward prediction
- RV34_MB_B_BACKWARD, ///< B-frame macroblock, backward prediction
- RV34_MB_SKIP, ///< Skipped block
- RV34_MB_B_INTERP, ///< Bidirectionally predicted B-frame macroblock, no motion vectors
- RV34_MB_P_16x8, ///< P-frame macroblock, 16x8 motion compensation partitions
- RV34_MB_P_8x16, ///< P-frame macroblock, 8x16 motion compensation partitions
- RV34_MB_B_DIRECT, ///< Bidirectionally predicted B-frame macroblock, two motion vectors
- RV34_MB_P_MIX16x16, ///< P-frame macroblock with DCs in a separate 4x4 block, one motion vector
- RV34_MB_TYPES
-};
-/** @} */
-
-/**
- * VLC tables used by decoder
- *
- * intra frame VLC sets do not contain some of those tables
- */
-typedef struct RV34VLC{
- VLC cbppattern[2]; ///< VLCs used for pattern of coded block patterns decoding
- VLC cbp[2][4]; ///< VLCs used for coded block patterns decoding
- VLC first_pattern[4]; ///< VLCs used for decoding coefficients in the first subblock
- VLC second_pattern[2]; ///< VLCs used for decoding coefficients in the subblocks 2 and 3
- VLC third_pattern[2]; ///< VLCs used for decoding coefficients in the last subblock
- VLC coefficient; ///< VLCs used for decoding big coefficients
-}RV34VLC;
-
-/** Essential slice information */
-typedef struct SliceInfo{
- int type; ///< slice type (intra, inter)
- int size; ///< size of the slice in bits
- int quant; ///< quantizer used for this slice
- int vlc_set; ///< VLCs used for this slice
- int start, end; ///< start and end macroblocks of the slice
- int header_size; ///< header size in bits
- int width; ///< coded width
- int height; ///< coded height
-}SliceInfo;
-
-/** Slice information saved for truncated slices */
-typedef struct SavedSliceInfo{
- uint8_t *data; ///< bitstream data
- int data_size; ///< data size
- int bits_used; ///< bits used up to last decoded block
- int mb_x, mb_y; ///< coordinates of the last decoded block
-}SavedSliceInfo;
-
-/** Decoder context */
-typedef struct RV34DecContext{
- MpegEncContext s;
- int mb_bits; ///< bits needed to read MB offet in slice header
- int *intra_types_hist; ///< old block types, used for prediction
- int *intra_types; ///< block types
- int intra_types_stride; ///< stride for block types data
- int block_start; ///< start of slice in blocks
- uint8_t *luma_dc_quant_i;///< luma subblock DC quantizer for intraframes
- uint8_t *luma_dc_quant_p;///< luma subblock DC quantizer for interframes
-
- int vlc_set; ///< index of currently selected VLC set
- RV34VLC *cur_vlcs; ///< VLC set used for current frame decoding
- int bits; ///< slice size in bits
- H264PredContext h; ///< functions for 4x4 and 16x16 intra block prediction
- SliceInfo si; ///< current slice information
- SliceInfo prev_si; ///< info for the saved slice
- uint8_t *slice_data; ///< saved slice data
-
- int *mb_type; ///< internal macroblock types
- int block_type; ///< current block type
- int luma_vlc; ///< which VLC set will be used for luma blocks decoding
- int chroma_vlc; ///< which VLC set will be used for chroma blocks decoding
- int is16; ///< current block has additional 16x16 specific features or not
- int dmv[4][2]; ///< differential motion vectors for the current macroblock
-
- int truncated; ///< flag signalling that slice ended prematurely
- SavedSliceInfo ssi; ///< data for truncated slice
-
- int rv30; ///< indicates which RV variasnt is currently decoded
- int rpr; ///< one field size in RV30 slice header
-
- int avail[4]; ///< whether left, top, top rights and top left MBs are available
-
- int (*parse_slice_header)(struct RV34DecContext *r, GetBitContext *gb, SliceInfo *si);
- int (*decode_intra_types)(struct RV34DecContext *r, GetBitContext *gb, int *dst);
- int (*decode_mb_info)(struct RV34DecContext *r);
-}RV34DecContext;
-
-static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];
-static VLC omega_part_vlc;
static VLC aic_top_vlc;
static VLC aic_mode1_vlc[AIC_MODE1_NUM], aic_mode2_vlc[AIC_MODE2_NUM];
static VLC ptype_vlc[NUM_PTYPE_VLCS], btype_vlc[NUM_BTYPE_VLCS];
/**
- * @defgroup vlc RV40 VLC generating functions
- * @{
- */
-
-/**
- * Generate VLC from codeword lengths
- */
-static int rv34_gen_vlc(const uint8_t *bits2, int size, VLC *vlc)
-{
- int i;
- int counts[17] = {0}, codes[17];
- uint16_t cw[size], syms[size];
- uint8_t bits[size];
- int maxbits = 0, realsize;
- int ret;
-
- realsize = 0;
- for(i = 0; i < size; i++){
- if(bits2[i]){
- bits[realsize] = bits2[i];
- syms[realsize] = i;
- realsize++;
- maxbits = FFMAX(maxbits, bits2[i]);
- counts[bits2[i]]++;
- }
- }
-
- size = realsize;
- 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[bits[i]]++;
-
- ret = init_vlc_sparse(vlc, FFMIN(maxbits, 9), size,
- bits, 1, 1,
- cw, 2, 2,
- syms, 2, 2, INIT_VLC_USE_STATIC);
- return ret;
-}
-
-/**
* Initialize all tables
*/
-static void rv34_init_tables()
+static void rv40_init_tables()
{
- int i, j, k;
-
- for(i = 0; i < NUM_INTRA_TABLES; i++){
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_intra_cbppatvlc_pointers[i][j], CBPPAT_VLC_SIZE, &intra_vlcs[i].cbppattern[j]);
- for(j = 0; j < 2; j++)
- for(k = 0; k < 4; k++)
- rv34_gen_vlc(rv34_intra_cbpvlc_pointers[i][j][k], CBP_VLC_SIZE, &intra_vlcs[i].cbp[j][k]);
- for(j = 0; j < 4; j++)
- rv34_gen_vlc(rv34_intra_firstpatvlc_pointers[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_intra_secondpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_intra_thirdpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j]);
- rv34_gen_vlc(rv34_intra_coeffvlc_pointers[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient);
- }
-
- for(i = 0; i < NUM_INTER_TABLES; i++){
- rv34_gen_vlc(rv34_inter_cbppatvlc_pointers[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0]);
- for(j = 0; j < 4; j++)
- rv34_gen_vlc(rv34_inter_cbpvlc_pointers[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_inter_firstpatvlc_pointers[i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_inter_secondpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j]);
- for(j = 0; j < 2; j++)
- rv34_gen_vlc(rv34_inter_thirdpatvlc_pointers[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j]);
- rv34_gen_vlc(rv34_inter_coeffvlc_pointers[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient);
- }
+ int i;
init_vlc(&aic_top_vlc, AIC_TOP_BITS, AIC_TOP_SIZE,
rv40_aic_top_vlc_bits, 1, 1,
@@ -238,10 +60,6 @@ static void rv34_init_tables()
aic_mode2_vlc_bits[i], 1, 1,
aic_mode2_vlc_codes[i], 2, 2, INIT_VLC_USE_STATIC);
}
- init_vlc_sparse(&omega_part_vlc, OMEGA_BITS, NUM_OMEGA,
- omega_part_vlc_bits, 1, 1,
- omega_part_vlc_codes, 1, 1,
- omega_part_vlc_syms, 1, 1, INIT_VLC_USE_STATIC);
for(i = 0; i < NUM_PTYPE_VLCS; i++)
init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE,
ptype_vlc_bits[i], 1, 1,
@@ -254,248 +72,6 @@ static void rv34_init_tables()
btype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC);
}
-/** @} */ // vlc group
-
-
-/**
- * @defgroup transform RV40 inverse transform functions
- * @{
- */
-
-/**
- * Real Video 4.0 inverse transform
- * Code is almost the same as in SVQ3, only scaling is different
- */
-static void rv34_intra_inv_transform(DCTELEM *block, const int offset){
- int temp[16];
- unsigned int i;
-
- for(i=0; i<4; i++){
- const int z0= 13*(block[offset+i+8*0] + block[offset+i+8*2]);
- const int z1= 13*(block[offset+i+8*0] - block[offset+i+8*2]);
- const int z2= 7* block[offset+i+8*1] - 17*block[offset+i+8*3];
- const int z3= 17* block[offset+i+8*1] + 7*block[offset+i+8*3];
-
- temp[4*i+0]= z0+z3;
- temp[4*i+1]= z1+z2;
- temp[4*i+2]= z1-z2;
- temp[4*i+3]= z0-z3;
- }
-
- for(i=0; i<4; i++){
- const int z0= 13*(temp[4*0+i] + temp[4*2+i]) + 0x200;
- const int z1= 13*(temp[4*0+i] - temp[4*2+i]) + 0x200;
- const int z2= 7* temp[4*1+i] - 17*temp[4*3+i];
- const int z3= 17* temp[4*1+i] + 7*temp[4*3+i];
-
- block[offset+i*8+0]= (z0 + z3)>>10;
- block[offset+i*8+1]= (z1 + z2)>>10;
- block[offset+i*8+2]= (z1 - z2)>>10;
- block[offset+i*8+3]= (z0 - z3)>>10;
- }
-
-}
-
-/**
- * RealVideo 4.0 inverse transform - special version
- *
- * Code is almost the same but final coefficients are multiplied by 1.5
- * and have no rounding
- */
-static void rv34_intra_inv_transform_noround(DCTELEM *block, const int offset){
- int temp[16];
- unsigned int i;
-
- for(i=0; i<4; i++){
- const int z0= 13*(block[offset+i+8*0] + block[offset+i+8*2]);
- const int z1= 13*(block[offset+i+8*0] - block[offset+i+8*2]);
- const int z2= 7* block[offset+i+8*1] - 17*block[offset+i+8*3];
- const int z3= 17* block[offset+i+8*1] + 7*block[offset+i+8*3];
-
- temp[4*i+0]= z0+z3;
- temp[4*i+1]= z1+z2;
- temp[4*i+2]= z1-z2;
- temp[4*i+3]= z0-z3;
- }
-
- for(i=0; i<4; i++){
- const int z0= 13*(temp[4*0+i] + temp[4*2+i]);
- const int z1= 13*(temp[4*0+i] - temp[4*2+i]);
- const int z2= 7* temp[4*1+i] - 17*temp[4*3+i];
- const int z3= 17* temp[4*1+i] + 7*temp[4*3+i];
-
- block[offset+i*8+0]= ((z0 + z3)*3)>>11;
- block[offset+i*8+1]= ((z1 + z2)*3)>>11;
- block[offset+i*8+2]= ((z1 - z2)*3)>>11;
- block[offset+i*8+3]= ((z0 - z3)*3)>>11;
- }
-
-}
-
-/** @} */ // transform
-
-
-/**
- * @defgroup block RV40 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 table2;
- static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000};
- static const int shifts[4] = { 0, 2, 8, 10 };
- int *curshift = shifts;
- int i, t, mask;
-
- code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2);
- pattern = code & 0xF;
- code >>= 4;
-
- table2 = rv34_count_ones[pattern];
-
- for(mask = 8; mask; mask >>= 1, curshift++){
- if(!(pattern & mask)) continue;
- t = get_vlc2(gb, vlc->cbp[table][table2].table, vlc->cbp[table][table2].bits, 1);
- cbp |= rv34_cbp_code[t] << curshift[0];
- }
-
- for(i = 0; i < 4; i++){
- t = modulo_three_table[code][i];
- 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 bistream and store it
- */
-static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc)
-{
- 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;
- }
-}
-
-/**
- * Decode 2x2 subblock of coefficients
- */
-static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc)
-{
- int coeffs[4];
-
- coeffs[0] = modulo_three_table[code][0];
- coeffs[1] = modulo_three_table[code][1];
- coeffs[2] = modulo_three_table[code][2];
- coeffs[3] = modulo_three_table[code][3];
- decode_coeff(dst , coeffs[0], 3, gb, vlc);
- if(!is_block2){
- decode_coeff(dst+1, coeffs[1], 2, gb, vlc);
- decode_coeff(dst+8, coeffs[2], 2, gb, vlc);
- }else{
- decode_coeff(dst+8, coeffs[1], 2, gb, vlc);
- decode_coeff(dst+1, coeffs[2], 2, gb, vlc);
- }
- decode_coeff(dst+9, coeffs[3], 2, gb, vlc);
-}
-
-/**
- * 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 inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc)
-{
- int code, pattern;
-
- code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2);
-
- pattern = code & 0x7;
-
- code >>= 3;
- decode_subblock(dst, code, 0, gb, &rvlc->coefficient);
-
- if(pattern & 4){
- code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
- decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient);
- }
- 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 + 8*2, code, 1, gb, &rvlc->coefficient);
- }
- if(pattern & 1){
- code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
- decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient);
- }
-}
-
-/**
- * Dequantize ordinary 4x4 block
- * @todo optimize
- */
-static inline void rv34_dequant4x4(DCTELEM *block, int offset, int Qdc, int Q)
-{
- int i, j;
-
- block += offset;
- block[0] = (block[0] * Qdc + 8) >> 4;
- for(i = 0; i < 4; i++)
- for(j = !i; j < 4; j++)
- block[j + i*8] = (block[j + i*8] * Q + 8) >> 4;
-}
-
-/**
- * Dequantize 4x4 block of DC values for 16x16 macroblock
- * @todo optimize
- */
-static inline void rv34_dequant4x4_16x16(DCTELEM *block, int offset, int Qdc, int Q)
-{
- int i;
-
- block += offset;
- for(i = 0; i < 3; i++)
- block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Qdc + 8) >> 4;
- for(; i < 16; i++)
- block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Q + 8) >> 4;
-}
-/** @} */ //block functions
-
-
-/**
- * @defgroup bitstream RV40 bitstream parsing
- * @{
- */
-
-static inline int decode210(GetBitContext *gb){
- if (get_bits1(gb))
- return 0;
- else
- return 2 - get_bits1(gb);
-}
-
/**
* Get stored dimension from bitstream
*
@@ -528,56 +104,11 @@ static void rv40_parse_picture_size(GetB
*h = get_dimension(gb, rv40_standard_heights, rv40_standard_heights2);
}
-/**
- * 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){
- if(quant < 19) quant += 10;
- else if(quant < 26) quant += 5;
- }
- if(mod == 1)
- if(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)]];
-}
-
-static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
-{
- int t, mb_bits;
- int w = r->s.width, h = r->s.height;
- int i, mb_size;
-
- memset(si, 0, sizeof(SliceInfo));
- get_bits(gb, 3);
- si->type = get_bits(gb, 2);
- if(si->type == 1) si->type = 0;
- if(get_bits1(gb))
- return -1;
- si->quant = get_bits(gb, 5);
- get_bits1(gb);
- t = get_bits(gb, 13);
- skip_bits(gb, r->rpr);
- si->vlc_set = 0;
- si->width = w;
- si->height = h;
- mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
- for(i = 0; i < 5; i++)
- if(rv34_mb_max_sizes[i] > mb_size)
- break;
- mb_bits = rv34_mb_bits_sizes[i];
- si->start = get_bits(gb, mb_bits);
- get_bits1(gb);
- si->header_size = get_bits_count(gb);
- return 0;
-}
-
static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
{
int t, mb_bits;
int w = r->s.width, h = r->s.height;
- int i, mb_size;
+ int mb_size;
memset(si, 0, sizeof(SliceInfo));
si->type = -1;
@@ -596,10 +127,7 @@ static int rv40_parse_slice_header(RV34D
si->width = w;
si->height = h;
mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
- for(i = 0; i < 5; i++)
- if(rv34_mb_max_sizes[i] > mb_size)
- break;
- mb_bits = rv34_mb_bits_sizes[i];
+ mb_bits = ff_rv34_get_start_offset(gb, mb_size);
si->start = get_bits(gb, mb_bits);
si->header_size = get_bits_count(gb);
@@ -607,76 +135,6 @@ static int rv40_parse_slice_header(RV34D
}
/**
- * Decode variable-length code constructed from variable-length codes
- * similar to Even-Rodeh and Elias Omega codes
- *
- * Code is constructed from bit chunks of even length (odd length means end of code)
- * and chunks are coded with variable-length codes too
- */
-int ff_rv34_get_omega(GetBitContext *gb)
-{
- int code = 1, t, tb;
-
- for(;;){
- t = get_vlc2(gb, omega_part_vlc.table, OMEGA_BITS, 1);
- tb = t >> 5;
- code = (code << tb) | (t & 0xF);
- if(t & 0x10) break;
- }
- return code;
-}
-
-/**
- * Decode signed integer variable-length code constructed from variable-length codes
- * similar to Even-Rodeh and Elias Omega codes
- *
- * Code is constructed from bit chunks of even length (odd length means end of code)
- * and chunks are coded with variable-length codes too
- */
-int ff_rv34_get_omega_signed(GetBitContext *gb)
-{
- int code;
-
- code = ff_rv34_get_omega(gb);
- if(code & 1)
- return -(code >> 1);
- else
- return code >> 1;
-}
-
-/**
- * Decode 4x4 intra types array
- */
-static int rv30_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int *dst)
-{
- int i, j, k;
- int A, B;
- int *ptr;
- int code;
-
- for(i = 0; i < 4; i++, dst += r->intra_types_stride){
- ptr = dst;
- for(j = 0; j < 4; j+= 2){
- code = (ff_rv34_get_omega(gb) - 1) << 1;
- if(code >= 81*2){
- av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n");
- return -1;
- }
- for(k = 0; k < 2; k++){
- A = ptr[-r->intra_types_stride] + 1;
- B = ptr[-1] + 1;
- *ptr++ = rv30_itype_from_context[A * 90 + B * 9 + rv30_itype_code[code + k]];
- if(ptr[-1] == 9){
- av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction mode\n");
- return -1;
- }
- }
- }
- }
- return 0;
-}
-
-/**
* Decode 4x4 intra types array
*/
static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int *dst)
@@ -740,43 +198,6 @@ static int rv40_decode_intra_types(RV34D
}
/**
- * Decode quantizer difference and return modified quantizer
- */
-static inline int rv34_decode_dquant(GetBitContext *gb, int quant)
-{
- if(get_bits1(gb))
- return av_clip(quant + rv34_dquant_tab[quant * 2 + get_bits1(gb)], 0, 31);
- else
- return get_bits(gb, 5);
-}
-
-/**
- * Decode macroblock information
- */
-static int rv30_decode_mb_info(RV34DecContext *r)
-{
- static const int rv30_p_types[6] = { RV34_MB_SKIP, RV34_MB_P_16x16, RV34_MB_P_8x8, -1, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 };
- static const int rv30_b_types[6] = { RV34_MB_SKIP, RV34_MB_B_INTERP, RV34_MB_B_FORWARD, RV34_MB_B_BACKWARD, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 };
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int code;
-
- code = ff_rv34_get_omega(gb) - 1;
- if(code > 11){
- av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n");
- return -1;
- }
- if(code > 5){
- av_log(s->avctx, AV_LOG_ERROR, "dquant needed\n");
- code -= 6;
- }
- if(s->pict_type != B_TYPE)
- return rv30_p_types[code];
- else
- return rv30_b_types[code];
-}
-
-/**
* Decode macroblock information
*/
static int rv40_decode_mb_info(RV34DecContext *r)
@@ -830,1342 +251,35 @@ static int rv40_decode_mb_info(RV34DecCo
return 0;
}
-/** @} */ //bitstream functions
-
-/**
- * @defgroup mv 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 };
-
-/**
- * Motion vectors prediction
- *
- * Motion prediction performed for the block by using median prediction of
- * motion vector from the left, top and right top blocks but in corener cases
- * some other vectors may be used instead
- */
-static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no)
-{
- MpegEncContext *s = &r->s;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
- int A[2], B[2], C[2];
- int no_A = 1, no_B = 1, no_C = 1;
- int i, j;
- int mx, my;
-
- memset(A, 0, sizeof(A));
- memset(B, 0, sizeof(B));
- memset(C, 0, sizeof(C));
- no_A = !r->avail[0];
- no_B = !r->avail[1];
- no_C = !r->avail[2];
- switch(block_type){
- case RV34_MB_P_16x16:
- case RV34_MB_P_MIX16x16:
- if(!no_C){
- 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];
- }
- break;
- case RV34_MB_P_8x8:
- mv_pos += (subblock_no & 1) + (subblock_no >> 1)*s->b8_stride;
- if(subblock_no & 1) no_A = 0;
- if(subblock_no & 2) no_B = 0;
- no_C |= (subblock_no == 3);
- if(subblock_no == 2) no_C = 0;
- if(!subblock_no) no_C = no_B;
- if(!no_C){
- 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];
- }
- if(subblock_no == 3){
- no_C = 0;
- 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];
- }
- break;
- case RV34_MB_P_16x8:
- mv_pos += subblock_no*s->b8_stride;
- no_B &= ~subblock_no;
- no_C |= subblock_no;
- if(!no_C){
- 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];
- }
- break;
- case RV34_MB_P_8x16:
- mv_pos += subblock_no;
- no_A &= ~subblock_no;
- if(!subblock_no) no_C = no_B;
- if(!no_C){
- 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];
- }
- break;
- default:
- no_A = no_B = no_C = 1;
- }
- if(!no_A){
- 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(!no_B){
- 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(no_C){
- if(no_B || (no_A && !r->rv30)){
- C[0] = A[0];
- C[1] = A[1];
- }else{
- 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];
- }
- }
- mx = mid_pred(A[0], B[0], C[0]);
- my = mid_pred(A[1], B[1], C[1]);
- mx += r->dmv[subblock_no][0];
- my += r->dmv[subblock_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;
- }
- }
-}
-
-/**
- * Predict motion vector for B-frame macroblock.
- */
-static inline void rv34_pred_b_vector(int A[2], int B[2], int C[2], int no_A, int no_B, int no_C, int *mx, int *my)
-{
- if(no_A + no_B + no_C){
- *mx = A[0] + B[0] + C[0];
- *my = A[1] + B[1] + C[1];
- if(no_A + no_B + no_C == 1){
- *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)
-{
- 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][2], B[2][2], C[2][2];
- int no_A[2], no_B[2], no_C[2];
- int c_mv_pos;
- int mx[2], my[2];
- int i, j;
-
- memset(A, 0, sizeof(A));
- memset(B, 0, sizeof(B));
- memset(C, 0, sizeof(C));
- memset(mx, 0, sizeof(mx));
- memset(my, 0, sizeof(my));
- if(!r->avail[0])
- no_A[0] = no_A[1] = 1;
- else{
- no_A[0] = no_A[1] = 0;
- if(r->mb_type[mb_pos - 1] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - 1] != RV34_MB_B_DIRECT)
- no_A[0] = 1;
- if(r->mb_type[mb_pos - 1] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - 1] != RV34_MB_B_DIRECT)
- no_A[1] = 1;
- if(!no_A[0]){
- A[0][0] = s->current_picture_ptr->motion_val[0][mv_pos - 1][0];
- A[0][1] = s->current_picture_ptr->motion_val[0][mv_pos - 1][1];
- }
- if(!no_A[1]){
- A[1][0] = s->current_picture_ptr->motion_val[1][mv_pos - 1][0];
- A[1][1] = s->current_picture_ptr->motion_val[1][mv_pos - 1][1];
- }
- }
- if(!r->avail[1]){
- no_B[0] = no_B[1] = 1;
- }else{
- no_B[0] = no_B[1] = 0;
- if(r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_DIRECT)
- no_B[0] = 1;
- if(r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - s->mb_stride] != RV34_MB_B_DIRECT)
- no_B[1] = 1;
- if(!no_B[0]){
- B[0][0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][0];
- B[0][1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][1];
- }
- if(!no_B[1]){
- B[1][0] = s->current_picture_ptr->motion_val[1][mv_pos - s->b8_stride][0];
- B[1][1] = s->current_picture_ptr->motion_val[1][mv_pos - s->b8_stride][1];
- }
- }
- if(r->avail[2]){
- no_C[0] = no_C[1] = 0;
- if(r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_DIRECT)
- no_C[0] = 1;
- if(r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - s->mb_stride + 1] != RV34_MB_B_DIRECT)
- no_C[1] = 1;
- c_mv_pos = mv_pos - s->b8_stride + 2;
- }else if(r->avail[3]){
- no_C[0] = no_C[1] = 0;
- if(r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_FORWARD && r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_DIRECT)
- no_C[0] = 1;
- if(r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_BACKWARD && r->mb_type[mb_pos - s->mb_stride - 1] != RV34_MB_B_DIRECT)
- no_C[1] = 1;
- c_mv_pos = mv_pos - s->b8_stride - 1;
- }else{
- no_C[0] = no_C[1] = 1;
- c_mv_pos = 0;
- }
- if(!no_C[0]){
- C[0][0] = s->current_picture_ptr->motion_val[0][c_mv_pos][0];
- C[0][1] = s->current_picture_ptr->motion_val[0][c_mv_pos][1];
- }
- if(!no_C[1]){
- C[1][0] = s->current_picture_ptr->motion_val[1][c_mv_pos][0];
- C[1][1] = s->current_picture_ptr->motion_val[1][c_mv_pos][1];
- }
- switch(block_type){
- case RV34_MB_B_FORWARD:
- rv34_pred_b_vector(A[0], B[0], C[0], no_A[0], no_B[0], no_C[0], &mx[0], &my[0]);
- r->dmv[1][0] = 0;
- r->dmv[1][1] = 0;
- break;
- case RV34_MB_B_BACKWARD:
- r->dmv[1][0] = r->dmv[0][0];
- r->dmv[1][1] = r->dmv[0][1];
- r->dmv[0][0] = 0;
- r->dmv[0][1] = 0;
- rv34_pred_b_vector(A[1], B[1], C[1], no_A[1], no_B[1], no_C[1], &mx[1], &my[1]);
- break;
- case RV34_MB_B_DIRECT:
- rv34_pred_b_vector(A[0], B[0], C[0], no_A[0], no_B[0], no_C[0], &mx[0], &my[0]);
- rv34_pred_b_vector(A[1], B[1], C[1], no_A[1], no_B[1], no_C[1], &mx[1], &my[1]);
- break;
- default:
- no_A[0] = no_A[1] = no_B[0] = no_B[1] = no_C[0] = no_C[1] = 1;
- }
-
- mx[0] += r->dmv[0][0];
- my[0] += r->dmv[0][1];
- mx[1] += r->dmv[1][0];
- my[1] += r->dmv[1][1];
- for(j = 0; j < 2; j++){
- for(i = 0; i < 2; i++){
- s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx[0];
- s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my[0];
- s->current_picture_ptr->motion_val[1][mv_pos + i + j*s->b8_stride][0] = mx[1];
- s->current_picture_ptr->motion_val[1][mv_pos + i + j*s->b8_stride][1] = my[1];
- }
- }
-}
-
-/**
- * Generic motion compensation function - hopefully compiler will optimize it for each case
- *
- * @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
- */
-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)
-{
- MpegEncContext *s = &r->s;
- uint8_t *Y, *U, *V, *srcY, *srcU, *srcV;
- int dxy, mx, my, 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;
-
- mx = s->current_picture_ptr->motion_val[0][mv_pos][0];
- my = s->current_picture_ptr->motion_val[0][mv_pos][1];
- srcY = s->last_picture_ptr->data[0];
- srcU = s->last_picture_ptr->data[1];
- srcV = s->last_picture_ptr->data[2];
- src_x = s->mb_x * 16 + xoff + (mx >> 2);
- src_y = s->mb_y * 16 + yoff + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (xoff >> 1) + (mx >> 3);
- uvsrc_y = s->mb_y * 8 + (yoff >> 1) + (my >> 3);
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
- if( (unsigned)(src_x - !!(mx&3)*2) > s->h_edge_pos - !!(mx&3)*2 - (width <<3) - 3
- || (unsigned)(src_y - !!(my&3)*2) > s->v_edge_pos - !!(my&3)*2 - (height<<3) - 3){
- uint8_t *uvbuf= s->edge_emu_buffer + 20 * s->linesize;
-
- srcY -= 2 + 2*s->linesize;
- ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+4, (height<<3)+4,
- 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,
- 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,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- srcU = uvbuf;
- srcV = uvbuf + 16;
- }
- dxy = ((my & 3) << 2) | (mx & 3);
- uvmx = mx & 6;
- uvmy = my & 6;
- 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;
- if(block_type == RV34_MB_P_16x8){
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- Y += 8;
- srcY += 8;
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[0] (U, srcU, s->uvlinesize, 4, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[0] (V, srcV, s->uvlinesize, 4, uvmx, uvmy);
- }else if(block_type == RV34_MB_P_8x16){
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- Y += 8 * s->linesize;
- srcY += 8 * s->linesize;
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[1] (U, srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[1] (V, srcV, s->uvlinesize, 8, uvmx, uvmy);
- }else if(block_type == RV34_MB_P_8x8){
- s->dsp.put_h264_qpel_pixels_tab[1][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[1] (U, srcU, s->uvlinesize, 4, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[1] (V, srcV, s->uvlinesize, 4, uvmx, uvmy);
- }else{
- s->dsp.put_h264_qpel_pixels_tab[0][dxy](Y, srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[0] (U, srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[0] (V, srcV, s->uvlinesize, 8, uvmx, uvmy);
- }
-}
-
-/**
- * B-frame specific motion compensation function
- *
- * @param r decoder context
- * @param block_type type of the current block
- */
-static inline void rv34_mc_b(RV34DecContext *r, const int block_type)
-{
- MpegEncContext *s = &r->s;
- uint8_t *srcY, *srcU, *srcV;
- int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
-
- if(block_type != RV34_MB_B_BACKWARD){
- mx = s->current_picture_ptr->motion_val[0][mv_pos][0];
- my = s->current_picture_ptr->motion_val[0][mv_pos][1];
- srcY = s->last_picture_ptr->data[0];
- srcU = s->last_picture_ptr->data[1];
- srcV = s->last_picture_ptr->data[2];
- }else{
- mx = s->current_picture_ptr->motion_val[1][mv_pos][0];
- my = s->current_picture_ptr->motion_val[1][mv_pos][1];
- srcY = s->next_picture_ptr->data[0];
- srcU = s->next_picture_ptr->data[1];
- srcV = s->next_picture_ptr->data[2];
- }
- if(block_type == RV34_MB_B_INTERP){
- mx += (s->next_picture_ptr->motion_val[0][mv_pos][0] + 1) >> 1;
- my += (s->next_picture_ptr->motion_val[0][mv_pos][1] + 1) >> 1;
- }
- src_x = s->mb_x * 16 + (mx >> 2);
- src_y = s->mb_y * 16 + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (mx >> 3);
- uvsrc_y = s->mb_y * 8 + (my >> 3);
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
- if( (unsigned)(src_x - !!(mx&3)*2) > s->h_edge_pos - !!(mx&3)*2 - 16 - 3
- || (unsigned)(src_y - !!(my&3)*2) > s->v_edge_pos - !!(my&3)*2 - 16 - 3){
- uint8_t *uvbuf= s->edge_emu_buffer + 20 * s->linesize;
-
- srcY -= 2 + 2*s->linesize;
- ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 16+4, 16+4,
- 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, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- srcU = uvbuf;
- srcV = uvbuf + 16;
- }
- dxy = ((my & 3) << 2) | (mx & 3);
- uvmx = mx & 6;
- uvmy = my & 6;
- s->dsp.put_h264_qpel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize);
- s->dsp.put_h264_chroma_pixels_tab[0] (s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.put_h264_chroma_pixels_tab[0] (s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
-}
-
-/**
- * B-frame specific motion compensation function - for direct/interpolated blocks
- *
- * @param r decoder context
- * @param block_type type of the current block
- */
-static inline void rv34_mc_b_interp(RV34DecContext *r, const int block_type)
-{
- MpegEncContext *s = &r->s;
- uint8_t *srcY, *srcU, *srcV;
- int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
-
- mx = s->current_picture_ptr->motion_val[1][mv_pos][0];
- my = s->current_picture_ptr->motion_val[1][mv_pos][1];
- if(block_type == RV34_MB_B_INTERP){
- mx -= s->next_picture_ptr->motion_val[0][mv_pos][0] >> 1;
- my -= s->next_picture_ptr->motion_val[0][mv_pos][1] >> 1;
- }
- srcY = s->next_picture_ptr->data[0];
- srcU = s->next_picture_ptr->data[1];
- srcV = s->next_picture_ptr->data[2];
-
- src_x = s->mb_x * 16 + (mx >> 2);
- src_y = s->mb_y * 16 + (my >> 2);
- uvsrc_x = s->mb_x * 8 + (mx >> 3);
- uvsrc_y = s->mb_y * 8 + (my >> 3);
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
- if( (unsigned)(src_x - !!(mx&3)*2) > s->h_edge_pos - !!(mx&3)*2 - 16 - 3
- || (unsigned)(src_y - !!(my&3)*2) > s->v_edge_pos - !!(my&3)*2 - 16 - 3){
- uint8_t *uvbuf= s->edge_emu_buffer + 20 * s->linesize;
-
- srcY -= 2 + 2*s->linesize;
- ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 16+4, 16+4,
- 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, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
- uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- srcU = uvbuf;
- srcV = uvbuf + 16;
- }
- dxy = ((my & 3) << 2) | (mx & 3);
- uvmx = mx & 6;
- uvmy = my & 6;
- s->dsp.avg_h264_qpel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize);
- s->dsp.avg_h264_chroma_pixels_tab[0] (s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
- s->dsp.avg_h264_chroma_pixels_tab[0] (s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
-}
-
-/**
- * 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;
-
- switch(block_type){
- case RV34_MB_TYPE_INTRA:
- case RV34_MB_TYPE_INTRA16x16:
- for(j = 0; j < 2; j++){
- for(i = 0; i < 2; i++){
- s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + i + j*s->b8_stride][0] = 0;
- s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + i + j*s->b8_stride][1] = 0;
- }
- }
- return 0;
- case RV34_MB_SKIP:
- r->dmv[0][0] = 0;
- r->dmv[0][1] = 0;
- if(s->pict_type == P_TYPE){
- rv34_pred_mv(r, block_type, 0);
- rv34_mc(r, block_type, 0, 0, 0, 2, 2);
- break;
- }
- case RV34_MB_B_INTERP:
- r->dmv[0][0] = 0;
- r->dmv[0][1] = 0;
- r->dmv[1][0] = 0;
- r->dmv[1][1] = 0;
- rv34_pred_mv_b (r, RV34_MB_B_INTERP);
- rv34_mc_b (r, RV34_MB_B_INTERP);
- rv34_mc_b_interp(r, RV34_MB_B_INTERP);
- break;
- case RV34_MB_P_16x16:
- case RV34_MB_P_MIX16x16:
- r->dmv[0][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[0][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv(r, block_type, 0);
- rv34_mc(r, block_type, 0, 0, 0, 2, 2);
- break;
- case RV34_MB_B_FORWARD:
- case RV34_MB_B_BACKWARD:
- r->dmv[0][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[0][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv_b (r, block_type);
- rv34_mc_b (r, block_type);
- break;
- case RV34_MB_P_16x8:
- case RV34_MB_P_8x16:
- case RV34_MB_B_DIRECT:
- r->dmv[0][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[0][1] = ff_rv34_get_omega_signed(gb);
- r->dmv[1][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[1][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv(r, block_type, 0);
- rv34_pred_mv(r, block_type, 1);
- if(block_type == RV34_MB_P_16x8){
- rv34_mc(r, block_type, 0, 0, 0, 2, 1);
- rv34_mc(r, block_type, 0, 8, s->b8_stride, 2, 1);
- }
- if(block_type == RV34_MB_P_8x16){
- rv34_mc(r, block_type, 0, 0, 0, 1, 2);
- rv34_mc(r, block_type, 8, 0, 1, 1, 2);
- }
- if(block_type == RV34_MB_B_DIRECT){
- rv34_pred_mv_b (r, block_type);
- rv34_mc_b (r, block_type);
- rv34_mc_b_interp(r, block_type);
- }
- break;
- case RV34_MB_P_8x8:
- for(i=0;i< 4;i++){
- r->dmv[i][0] = ff_rv34_get_omega_signed(gb);
- r->dmv[i][1] = ff_rv34_get_omega_signed(gb);
- rv34_pred_mv(r, block_type, i);
- rv34_mc(r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1);
- }
- break;
- }
-
- return 0;
-}
-/** @} */ // mv group
-
-/**
- * @defgroup recons Macroblock reconstruction functions
- * @{
- */
-/** Mapping of RV40 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 RV40 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 no_up, int no_left, int no_down, int no_right)
-{
- uint8_t *prev = dst - stride + 4;
- uint32_t topleft;
-
- if(no_up && no_left)
- itype = DC_128_PRED;
- else if(no_up){
- if(itype == VERT_PRED) itype = HOR_PRED;
- if(itype == DC_PRED) itype = LEFT_DC_PRED;
- }else if(no_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(no_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(no_right && !no_up){
- topleft = dst[-stride + 3] * 0x01010101;
- prev = &topleft;
- }
- r->h.pred4x4[itype](dst, prev, stride);
-}
-
-/** add_pixels_clamped for 4x4 block */
-static void rv34_add_4x4_block(uint8_t *dst, int stride, DCTELEM block[64], int off)
-{
- int x, y;
- for(y = 0; y < 4; y++)
- for(x = 0; x < 4; x++)
- dst[x + y*stride] = av_clip_uint8(dst[x + y*stride] + block[off + x+y*8]);
-}
-
-static void rv34_output_macroblock(RV34DecContext *r, int *intra_types, int cbp, int is16)
-{
- MpegEncContext *s = &r->s;
- DSPContext *dsp = &s->dsp;
- int i, j;
- uint8_t *Y, *YY, *U, *V;
- int no_up, no_left, no_topright, itype;
-
- no_up = !r->avail[1];
- Y = s->dest[0];
- U = s->dest[1];
- V = s->dest[2];
- if(!is16){
- for(j = 0; j < 4; j++){
- no_left = !r->avail[0];
- YY = Y;
- for(i = 0; i < 4; i++, cbp >>= 1, YY += 4){
- no_topright = no_up || (i==3 && j) || (i==3 && !j && (s->mb_x-1) == s->mb_width);
- rv34_pred_4x4_block(r, YY, s->linesize, ittrans[intra_types[i]], no_up, no_left, i || (j==3), no_topright);
- no_left = 0;
- if(!(cbp & 1)) continue;
- rv34_add_4x4_block(YY, s->linesize, s->block[(i>>1)+(j&2)], (i&1)*4+(j&1)*32);
- }
- no_up = 0;
- Y += s->linesize * 4;
- intra_types += r->intra_types_stride;
- }
- intra_types -= r->intra_types_stride * 4;
- no_up = !r->avail[1];
- for(j = 0; j < 2; j++){
- no_left = !r->avail[0];
- for(i = 0; i < 2; i++, cbp >>= 1, no_left = 0){
- no_topright = no_up || (i && j) || (i && !j && (s->mb_x-1) == s->mb_width);
- 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]], no_up, no_left, i || j, no_topright);
- 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]], no_up, no_left, i || j, no_topright);
- if(cbp & 0x01)
- rv34_add_4x4_block(U + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[4], i*4+j*32);
- if(cbp & 0x10)
- rv34_add_4x4_block(V + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[5], i*4+j*32);
- }
- no_up = 0;
- }
- }else{
- no_left = !r->avail[0];
- itype = ittrans16[intra_types[0]];
- if(no_up && no_left)
- itype = DC_128_PRED8x8;
- else if(no_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(no_left){
- if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8;
- if(itype == HOR_PRED8x8) itype = VERT_PRED8x8;
- if(itype == DC_PRED8x8) itype = TOP_DC_PRED8x8;
- }
- r->h.pred16x16[itype](Y, s->linesize);
- dsp->add_pixels_clamped(s->block[0], Y, s->current_picture.linesize[0]);
- dsp->add_pixels_clamped(s->block[1], Y + 8, s->current_picture.linesize[0]);
- Y += s->current_picture.linesize[0] * 8;
- dsp->add_pixels_clamped(s->block[2], Y, s->current_picture.linesize[0]);
- dsp->add_pixels_clamped(s->block[3], Y + 8, s->current_picture.linesize[0]);
-
- itype = ittrans16[intra_types[0]];
- if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
- if(no_up && no_left)
- itype = DC_128_PRED8x8;
- else if(no_up){
- if(itype == VERT_PRED8x8) itype = HOR_PRED8x8;
- if(itype == DC_PRED8x8) itype = LEFT_DC_PRED8x8;
- }else if(no_left){
- if(itype == HOR_PRED8x8) itype = VERT_PRED8x8;
- if(itype == DC_PRED8x8) itype = TOP_DC_PRED8x8;
- }
- r->h.pred8x8[itype](U, s->uvlinesize);
- dsp->add_pixels_clamped(s->block[4], U, s->uvlinesize);
- r->h.pred8x8[itype](V, s->uvlinesize);
- dsp->add_pixels_clamped(s->block[5], V, s->uvlinesize);
- }
-}
-
-/** @} */ // recons group
-
-/**
- * @addtogroup bitstream
- * Decode macroblock header and return CBP in case of success, -1 otherwise.
- */
-static int rv34_decode_mb_header(RV34DecContext *r, int *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->rv30){
- r->is16 = 0;
- switch(decode210(gb)){
- case 0: // 16x16 block
- r->is16 = 1;
- break;
- case 1:
- break;
- case 2:
- av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
- // q = decode_dquant(gb);
- break;
- }
- 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 if(!r->si.type && r->rv30){
- r->is16 = get_bits1(gb);
- 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 == P_TYPE)
- r->mb_type[mb_pos] = RV34_MB_P_16x16;
- if(s->pict_type == B_TYPE)
- r->mb_type[mb_pos] = RV34_MB_B_INTERP;
- }
- 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){
- for(i = 0; i < 16; i++)
- intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 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){
- if(r->decode_intra_types(r, gb, intra_types) < 0)
- return -1;
- r->chroma_vlc = 0;
- r->luma_vlc = 1;
- }else{
- t = get_bits(gb, 2);
- for(i = 0; i < 16; i++)
- intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = t;
- r->chroma_vlc = 0;
- r->luma_vlc = 2;
- }
- 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);
-}
-
-/**
- * @addtogroup recons
- * @{
- */
-/** Mask for retrieving all bits in coded block pattern
- * corresponding to one 8x8 block.
- */
-#define LUMA_CBP_BLOCK_MASK 0x303
-
-#define U_CBP_MASK 0x0F0000
-#define V_CBP_MASK 0xF00000
-
-
-static void rv34_apply_differences(RV34DecContext *r, int cbp)
-{
- static const int shifts[4] = { 0, 2, 8, 10 };
- MpegEncContext *s = &r->s;
- int i;
-
- for(i = 0; i < 4; i++)
- if(cbp & (LUMA_CBP_BLOCK_MASK << shifts[i]))
- s->dsp.add_pixels_clamped(s->block[i], s->dest[0] + (i & 1)*8 + (i&2)*4*s->linesize, s->linesize);
- if(cbp & U_CBP_MASK)
- s->dsp.add_pixels_clamped(s->block[4], s->dest[1], s->uvlinesize);
- if(cbp & V_CBP_MASK)
- s->dsp.add_pixels_clamped(s->block[5], s->dest[2], s->uvlinesize);
-}
-
-static int rv34_decode_macroblock(RV34DecContext *r, int *intra_types)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int cbp, cbp2;
- int i, blknum, blkoff;
- DCTELEM block16[64];
- int luma_dc_quant;
-
- // calculate which neighbours are available
- memset(r->avail, 0, sizeof(r->avail));
- if(s->mb_x && !(s->first_slice_line && s->mb_x == s->resync_mb_x))
- r->avail[0] = 1;
- if(!s->first_slice_line)
- r->avail[1] = 1;
- if((s->mb_x+1) < s->mb_width && (!s->first_slice_line || (s->first_slice_line && (s->mb_x+1) == s->resync_mb_x)))
- r->avail[2] = 1;
- if(s->mb_x && !s->first_slice_line && !((s->mb_y-1)==s->resync_mb_y && s->mb_x == s->resync_mb_x))
- r->avail[3] = 1;
-
- s->qscale = r->si.quant;
- cbp = cbp2 = rv34_decode_mb_header(r, intra_types);
-
- if(cbp == -1)
- return -1;
-
- luma_dc_quant = r->si.type ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale];
- if(r->is16){
- memset(block16, 0, sizeof(block16));
- rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0);
- rv34_dequant4x4_16x16(block16, 0, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
- rv34_intra_inv_transform_noround(block16, 0);
- }
-
- for(i = 0; i < 16; i++, cbp >>= 1){
- if(!r->is16 && !(cbp & 1)) continue;
- blknum = ((i & 2) >> 1) + ((i & 8) >> 2);
- blkoff = ((i & 1) << 2) + ((i & 4) << 3);
- if(cbp & 1)
- rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0);
- if((cbp & 1) || r->is16){
- rv34_dequant4x4(s->block[blknum], blkoff, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
- if(r->is16) //FIXME: optimize
- s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)];
- rv34_intra_inv_transform(s->block[blknum], blkoff);
- }
- }
- if(r->block_type == RV34_MB_P_MIX16x16)
- r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
- for(; i < 24; i++, cbp >>= 1){
- if(!(cbp & 1)) continue;
- blknum = ((i & 4) >> 2) + 4;
- blkoff = ((i & 1) << 2) + ((i & 2) << 4);
- rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1);
- rv34_dequant4x4(s->block[blknum], blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]);
- rv34_intra_inv_transform(s->block[blknum], blkoff);
- }
- if(IS_INTRA(s->current_picture_ptr->mb_type[s->mb_x + s->mb_y*s->mb_stride]))
- rv34_output_macroblock(r, intra_types, cbp2, r->is16);
- else
- rv34_apply_differences(r, cbp2);
-
- return 0;
-}
-
-static int check_slice_end(RV34DecContext *r, MpegEncContext *s)
-{
- int bits;
- if(r->s.mb_skip_run > 1)
- return 0;
- if(s->mb_y >= s->mb_height)
- return 1;
- bits = r->bits - get_bits_count(&s->gb);
- if(bits < 0 || (bits < 8 && !show_bits(&s->gb, bits)))
- return 1;
- return 0;
-}
-
-static inline int slice_compare(SliceInfo *si1, SliceInfo *si2)
-{
- return si1->type != si2->type ||
- si1->start >= si2->start ||
- si1->width != si2->width ||
- si1->height != si2->height;
-}
-
-static int rv34_decode_slice(RV34DecContext *r, int size, int end, int *last)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int mb_pos;
- int res;
- int old_mb_x = r->ssi.mb_x, old_mb_y = r->ssi.mb_y;
- *last = 1;
-
- init_get_bits(&r->s.gb, r->slice_data, r->si.size);
- res = r->parse_slice_header(r, gb, &r->si);
- if((res < 0 && !s->current_picture_ptr) || (r->prev_si.type == -1 && r->si.start)){
- av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n");
- *last = 0;
- return -1;
- }
- if(res < 0 || (r->prev_si.type != -1 && slice_compare(&r->prev_si, &r->si))){
- r->ssi.data = av_realloc(r->ssi.data, r->ssi.data_size + (size>>3));
- memcpy(r->ssi.data + r->ssi.data_size, r->slice_data, size >> 3);
- r->ssi.data_size += size >> 3; // XXX: overflow check?
- size = r->ssi.data_size * 8;
- init_get_bits(&r->s.gb, r->ssi.data, r->ssi.data_size * 8);
- r->si = r->prev_si;
- skip_bits(gb, r->ssi.bits_used);
- s->mb_x = r->ssi.mb_x;
- s->mb_y = r->ssi.mb_y;
- r->si.start = s->mb_x + s->mb_y * s->mb_width;
- r->truncated = 1;
- }
-
- if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
- if(s->width != r->si.width || s->height != r->si.height /*&& avcodec_check_dimensions(s->avctx, r->si.width, r->si.height) >= 0 */){
- av_log(s->avctx, AV_LOG_DEBUG, "Changing dimensions to %dx%d\n", r->si.width,r->si.height);
- MPV_common_end(s);
- s->width = r->si.width;
- s->height = r->si.height;
- if(MPV_common_init(s) < 0)
- return -1;
- }
- s->pict_type = r->si.type ? r->si.type : I_TYPE;
- if(MPV_frame_start(s, s->avctx) < 0)
- return -1;
- ff_er_frame_start(s);
- s->current_picture_ptr = &s->current_picture;
- s->mb_x = s->mb_y = 0;
- r->truncated = 0;
- }
-
- r->si.size = size;
- r->si.end = end;
- s->qscale = r->si.quant;
- r->bits = r->si.size;
- r->block_start = r->si.start;
- s->mb_num_left = r->si.end - r->si.start;
- r->s.mb_skip_run = 0;
-
- r->prev_si = r->si;
-
- mb_pos = s->mb_x + s->mb_y * s->mb_width;
- if(!r->truncated && r->block_start != mb_pos){
- av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->block_start, mb_pos);
- s->mb_x = r->block_start % s->mb_width;
- s->mb_y = r->block_start / s->mb_width;
- }
- if(!r->truncated){
- memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(int));
- 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) && s->mb_num_left-- && s->mb_y < s->mb_height) {
- ff_update_block_index(s);
- s->dsp.clear_blocks(s->block[0]);
-
- /* save information about decoded position in case of truncated slice */
- if(r->bits > get_bits_count(gb)){
- r->ssi.bits_used = get_bits_count(gb);
- r->ssi.mb_x = s->mb_x;
- r->ssi.mb_y = s->mb_y;
- }
-
- if(rv34_decode_macroblock(r, r->intra_types + (s->mb_x + 1) * 4) < 0)
- break;
- 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(int));
- memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(int));
- }
- if(s->mb_x == s->resync_mb_x)
- s->first_slice_line=0;
- }
- if(!r->truncated)
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
- else // add only additionally decoded blocks
- ff_er_add_slice(s, old_mb_x+1, old_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
- r->truncated = 0;
- *last = 0;
- if(s->mb_y >= s->mb_height)
- *last = 1;
- if(r->bits > get_bits_count(gb) && show_bits(gb, r->bits-get_bits_count(gb)))
- *last = 1;
-
- r->ssi.data = av_realloc(r->ssi.data, r->bits >> 3);
- r->ssi.data_size = r->bits >> 3;
- memcpy(r->ssi.data, r->slice_data, r->bits >> 3);
- return 0;
-}
-
-#define CLIP_SYMM(a, b) av_clip(a, -(b), b)
-/**
- * Weaker deblocking
- */
-static inline void rv34_weak_loop_filter(uint8_t *src, const int step,
- const int flag0, const int flag1, const int mult,
- const int lim0, const int lim1, const int lim2, const int thr1,
- const int S0, const int S1, const int S2, const int S3)
-{
- uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
- int t, diff;
-
- t = src[0*step] - src[-1*step];
- if(!t) return;
- t = (mult * FFABS(t)) >> 7;
- if(t > 3) return;
- if(flag0 && flag1 && t > 2) return;
- t = src[-1*step] - src[0*step];
-
- if(flag0 && flag1)
- diff = (src[-2*step] - src[1*step] + t*4 + 4) >> 3;
- else
- diff = (t + 1) >> 1;
- diff = CLIP_SYMM(diff, lim2);
- src[-1*step] = cm[src[-1*step] + diff];
- src[ 0*step] = cm[src[ 0*step] - diff];
- if(FFABS(S1) <= thr1 && flag0){
- t = (S0 + S1 - diff) >> 1;
- src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim1)];
- }
- if(FFABS(S3) <= thr1 && flag1){
- t = (S2 + S3 + diff) >> 1;
- src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim0)];
- }
-}
-
-/**
- * This macro is used for calculating 25*x0+26*x1+26*x2+26*x3+25*x4
- * or 25*x0+26*x1+51*x2+26*x3
- * parameter sub - index of the value with coefficient = 25
- * parameter last - index of the value with coefficient 25 or 51
- */
-#define RV34_STRONG_FILTER(src, step, start, last, sub) \
- 26*(src[start*step] + src[(start+1)*step] + src[(start+2)*step] + src[(start+3)*step] + src[last*step]) - src[last*step] - src[sub*step]
-/**
- * Deblocking filter, the alternated version from JVT-A003r1 H.26L draft.
- */
-static inline void rv34_adaptive_loop_filter(uint8_t *src, const int step, const int stride, const int dmode, const int lim0, const int lim1, const int mult, const int thr0, const int thr1, const int chroma, const int edge)
-{
- int diffs[4][4];
- int s0 = 0, s1 = 0, s2 = 0, s3 = 0;
- uint8_t *ptr;
- int flag0 = 1, flag1 = 1;
- int llim0 = 3, llim1 = 3;
- int i, t, sflag;
- int p0, p1;
- int v88;
-
- for(i = 0, ptr = src; i < 4; i++, ptr += stride){
- diffs[i][0] = ptr[-2*step] - ptr[-1*step];
- diffs[i][1] = ptr[-2*step] - ptr[-3*step];
- diffs[i][2] = ptr[ 1*step] - ptr[ 0*step];
- diffs[i][3] = ptr[ 1*step] - ptr[ 2*step];
- s0 += diffs[i][0];
- s1 += diffs[i][1];
- s2 += diffs[i][2];
- s3 += diffs[i][3];
- }
- if(FFABS(s0) >= (thr0<<2)){
- llim0 = 1;
- flag0 = 0;
- }
- if(FFABS(s2) >= (thr0<<2)){
- llim1 = 1;
- flag1 = 0;
- }
- if(llim0 + llim1 == 2)
- return;
-
- if(!edge)
- flag0 = flag1 = 0;
- if(flag0 && FFABS(s1) >= thr1)
- flag0 = 0;
- if(flag1 && FFABS(s3) >= thr1)
- flag1 = 0;
-
- v88 = (lim0 + lim1 + llim0 + llim1) >> 1;
- if(flag0 + flag1 == 2){ /* strong filtering */
- for(i = 0; i < 4; i++, src += stride){
- t = src[0*step] - src[-1*step];
- if(!t) continue;
- sflag = (mult * FFABS(t)) >> 7;
- if(sflag > 1) continue;
-
- p0 = (RV34_STRONG_FILTER(src, step, -3, 1, -3) + rv34_dither_l[dmode + i]) >> 7;
- p1 = (RV34_STRONG_FILTER(src, step, -1, 3, -1) + rv34_dither_r[dmode + i]) >> 7;
- if(!sflag){
- src[-1*step] = p0;
- src[ 0*step] = p1;
- }else{
- if((src[-1*step] - p0) >= -v88 && (src[-1*step] - p0) <= v88)
- src[-1*step] = p0;
- else
- src[-1*step] = p1;
- if((src[ 0*step] - p1) >= -v88 && (src[ 0*step] - p1) <= v88)
- src[ 0*step] = p1;
- else
- src[ 0*step] = src[-1*step];
- }
- p0 = (RV34_STRONG_FILTER(src, step, -4, 0, -4) + rv34_dither_l[dmode + i]) >> 7;
- p1 = (RV34_STRONG_FILTER(src, step, -1, 3, -1) + rv34_dither_r[dmode + i]) >> 7;
- if(!sflag){
- src[-2*step] = p0;
- src[ 1*step] = p1;
- }else{
- if((src[-2*step] - p0) >= -v88 && (src[-2*step] - p0) <= v88)
- src[-2*step] = p0;
- else
- src[-2*step] += v88;
- if((src[ 1*step] - p1) >= -v88 && (src[ 1*step] - p1) <= v88)
- src[ 1*step] = p1;
- else
- src[ 1*step] += v88;
- }
- if(!chroma){
- src[-3*step] = (RV34_STRONG_FILTER(src, step, -4, -1, -3) + 64) >> 7;
- src[ 2*step] = (RV34_STRONG_FILTER(src, step, 0, 0, 2) + 64) >> 7;
- }
- }
- }else if(llim0 == 3 && llim1 == 3)
- for(i = 0; i < 4; i++, src += stride)
- rv34_weak_loop_filter(src, step, 1, 1, mult, lim0, lim1, v88, thr1,
- diffs[i][0], diffs[i][1], diffs[i][2], diffs[i][3]);
- else
- for(i = 0; i < 4; i++, src += stride)
- rv34_weak_loop_filter(src, step, llim0==3, llim1==3, mult, lim0>>1, lim1>>1, v88>>1, thr1,
- diffs[i][0], diffs[i][1], diffs[i][2], diffs[i][3]);
-}
-
-static void rv34_v_loop_filter(uint8_t *src, int stride, int dmode, int lim0, int lim1, int mult, int thr0, int thr1, int chroma, int edge){
- rv34_adaptive_loop_filter(src, 1, stride, dmode, lim0, lim1, mult, thr0, thr1, chroma, edge);
-}
-static void rv34_h_loop_filter(uint8_t *src, int stride, int dmode, int lim0, int lim1, int mult, int thr0, int thr1, int chroma, int edge){
- rv34_adaptive_loop_filter(src, stride, 1, dmode, lim0, lim1, mult, thr0, thr1, chroma, edge);
-}
-
-static void rv34_loop_filter(RV34DecContext *r)
-{
- MpegEncContext *s = &r->s;
- int mb_pos;
- int i, j;
- int no_up, no_left;
- uint8_t *Y, *U, *V;
- const int alpha = rv34_alpha_tab[s->qscale], beta = rv34_beta_tab[s->qscale];
- //XXX these are probably not correct
- const int thr = s->qscale, lim0 = rv34_filter_clip_tbl[1][s->qscale], lim1 = rv34_filter_clip_tbl[2][s->qscale];
-
- mb_pos = s->resync_mb_x + s->resync_mb_y * s->mb_stride;
- memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(int));
- s->first_slice_line = 1;
- s->mb_x= s->resync_mb_x;
- s->mb_y= s->resync_mb_y;
- ff_init_block_index(s);
- while(s->mb_num_left-- && s->mb_y < s->mb_height) {
- ff_update_block_index(s);
- if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
- no_up = s->first_slice_line || !IS_INTRA(s->current_picture_ptr->mb_type[mb_pos - s->mb_stride]);
- no_left = !s->mb_x || (s->first_slice_line && s->mb_x == s->resync_mb_x) || !IS_INTRA(s->current_picture_ptr->mb_type[mb_pos - 1]);
- for(j = 0; j < 4; j++){
- for(i = 0; i < 4; i++){
- Y = s->dest[0] + i*4 + j*4*s->linesize;
- if(!j && !no_up)
- rv34_h_loop_filter(Y, s->linesize, i*4+j, lim0, lim1, alpha, beta, thr, 0, 1);
- if(j != 3)
- rv34_h_loop_filter(Y + 4*s->linesize, s->linesize, i*4+j, lim0, lim1, alpha, beta, thr, 0, 0);
- if(i || !no_left)
- rv34_v_loop_filter(Y, s->linesize, i*4+j, lim0, lim1, alpha, beta, thr, 0, !i);
- }
- }
- }
- if (++s->mb_x == s->mb_width) {
- s->mb_x = 0;
- s->mb_y++;
- ff_init_block_index(s);
- mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- }
- if(s->mb_x == s->resync_mb_x)
- s->first_slice_line=0;
- }
-
-}
-/** @} */ // recons group end
-
/**
* Initialize decoder
- * @todo Maybe redone in some other way
*/
-static int rv34_decode_init(AVCodecContext *avctx)
+static int rv40_decode_init(AVCodecContext *avctx)
{
RV34DecContext *r = avctx->priv_data;
- MpegEncContext *s = &r->s;
-
static int tables_done = 0;
- r->rv30 = (avctx->codec_id == CODEC_ID_RV30);
- 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 = PIX_FMT_YUV420P;
- avctx->has_b_frames = 1;
- s->low_delay = 0;
-
- if (MPV_common_init(s) < 0)
- return -1;
-
- ff_h264_pred_init(&r->h, CODEC_ID_RV40);
-
- r->intra_types_stride = (s->mb_width + 1) * 4;
- r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(int));
- 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(int));
-
+ r->rv30 = 0;
+ ff_rv34_decode_init(avctx);
if(!tables_done){
- rv34_init_tables();
+ rv40_init_tables();
tables_done = 1;
}
- r->prev_si.type = -1;
- if(r->rv30){
- if(avctx->extradata_size < 2){
- av_log(avctx, AV_LOG_ERROR, "Extradata is too small\n");
- return -1;
- }
- r->rpr = (avctx->extradata[1] & 7) >> 1;
- r->rpr = FFMIN(r->rpr + 1, 3);
- }
- r->parse_slice_header = r->rv30 ? rv30_parse_slice_header : rv40_parse_slice_header;
- r->decode_intra_types = r->rv30 ? rv30_decode_intra_types : rv40_decode_intra_types;
- r->decode_mb_info = r->rv30 ? rv30_decode_mb_info : rv40_decode_mb_info;
- if(r->rv30){
- r->luma_dc_quant_i = rv30_luma_dc_quant;
- r->luma_dc_quant_p = rv30_luma_dc_quant;
- }else{
- r->luma_dc_quant_i = rv40_luma_quant[0];
- r->luma_dc_quant_p = rv40_luma_quant[1];
- }
- return 0;
-}
-
-static int rv34_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- uint8_t *buf, int buf_size)
-{
- RV34DecContext *r = avctx->priv_data;
- MpegEncContext *s = &r->s;
- AVFrame *pict = data;
- SliceInfo si;
- int i;
- int slice_count, *slice_offset;
- int zero_offset = {0};
- int last = 0;
-
- /* no supplementary picture */
- if (buf_size == 0) {
- /* special case for last picture */
- if (s->low_delay==0 && s->next_picture_ptr) {
- *pict= *(AVFrame*)s->next_picture_ptr;
- s->next_picture_ptr= NULL;
-
- *data_size = sizeof(AVFrame);
- }
- }
-
- if(avctx->slice_count){
- slice_count = avctx->slice_count;
- slice_offset = avctx->slice_offset;
- }else{
- slice_count = 1;
- slice_offset = &zero_offset;
- }
-
- for(i=0; i<slice_count; i++){
- int offset= slice_offset[i];
- int size;
-
- if(i+1 == slice_count)
- size= buf_size - offset;
- else
- size= slice_offset[i+1] - offset;
-
- r->si.size = size * 8;
- r->si.end = s->mb_width * s->mb_height;
- if(i+1 < slice_count){
- init_get_bits(&s->gb, buf+slice_offset[i+1], (buf_size-slice_offset[i+1])*8);
- if(r->parse_slice_header(r, &r->s.gb, &si) < 0){
- if(i+2 < slice_count)
- size = slice_offset[i+2] - offset;
- else
- size = buf_size - offset;
- r->si.size = size * 8;
- }else
- r->si.end = si.start;
- }
- r->slice_data = buf + offset;
- rv34_decode_slice(r, r->si.size, r->si.end, &last);
- if(last)
- break;
- s->mb_num_left = r->si.end - r->si.start;
- //rv40_postprocess(r);
- }
-
- if(last){
- r->prev_si.type = -1;
- ff_er_frame_end(s);
- MPV_frame_end(s);
- if (s->pict_type == B_TYPE || s->low_delay) {
- *pict= *(AVFrame*)s->current_picture_ptr;
- } else if (s->last_picture_ptr != NULL) {
- *pict= *(AVFrame*)s->last_picture_ptr;
- }
-
- if(s->last_picture_ptr || s->low_delay){
- *data_size = sizeof(AVFrame);
- ff_print_debug_info(s, pict);
- }
- s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
- }
- return buf_size;
-}
-
-static int rv34_decode_end(AVCodecContext *avctx)
-{
- RV34DecContext *r = avctx->priv_data;
-
- MPV_common_end(&r->s);
-
- av_freep(&r->intra_types_hist);
- r->intra_types = NULL;
- av_freep(&r->mb_type);
- av_freep(&r->ssi.data);
-
+ r->parse_slice_header = rv40_parse_slice_header;
+ r->decode_intra_types = rv40_decode_intra_types;
+ r->decode_mb_info = rv40_decode_mb_info;
+ r->luma_dc_quant_i = rv40_luma_quant[0];
+ r->luma_dc_quant_p = rv40_luma_quant[1];
return 0;
}
-AVCodec rv30_decoder = {
- "rv30",
- CODEC_TYPE_VIDEO,
- CODEC_ID_RV30,
- sizeof(RV34DecContext),
- rv34_decode_init,
- NULL,
- rv34_decode_end,
- rv34_decode_frame,
-};
-
AVCodec rv40_decoder = {
"rv40",
CODEC_TYPE_VIDEO,
CODEC_ID_RV40,
sizeof(RV34DecContext),
- rv34_decode_init,
+ rv40_decode_init,
NULL,
- rv34_decode_end,
- rv34_decode_frame,
+ ff_rv34_decode_end,
+ ff_rv34_decode_frame,
};
Modified: rv40/rv40data.h
==============================================================================
--- rv40/rv40data.h (original)
+++ rv40/rv40data.h Wed Sep 19 18:55:05 2007
@@ -30,21 +30,6 @@
#include <stdint.h>
/**
- * Number of ones in nibble minus one
- */
-static const uint8_t rv34_count_ones[16] = {
- 0, 0, 0, 1, 0, 1, 1, 2, 0, 1, 1, 2, 1, 2, 2, 3
-};
-
-/**
- * Values used to reconstruct coded block pattern
- */
-static const uint8_t rv34_cbp_code[16] = {
- 0x00, 0x20, 0x10, 0x30, 0x02, 0x22, 0x12, 0x32,
- 0x01, 0x21, 0x11, 0x31, 0x03, 0x23, 0x13, 0x33
-};
-
-/**
* Standard widths and heights coded in RV40
*/
//@{
@@ -53,42 +38,6 @@ static const int rv40_standard_heights[]
static const int rv40_standard_heights2[] = { 180, 360, 576, 0};
//@}
-/**
- * Precalculated results of division by three and modulo three for values 0-107
- *
- * A lot of four-tuples in RV40 are represented as c0*27+c1*9+c2*3+c3
- * This table allows conversion from value back to vector
- */
-static const uint8_t modulo_three_table[108][4] = {
- { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0, 2 }, { 0, 0, 1, 0 },
- { 0, 0, 1, 1 }, { 0, 0, 1, 2 }, { 0, 0, 2, 0 }, { 0, 0, 2, 1 },
- { 0, 0, 2, 2 }, { 0, 1, 0, 0 }, { 0, 1, 0, 1 }, { 0, 1, 0, 2 },
- { 0, 1, 1, 0 }, { 0, 1, 1, 1 }, { 0, 1, 1, 2 }, { 0, 1, 2, 0 },
- { 0, 1, 2, 1 }, { 0, 1, 2, 2 }, { 0, 2, 0, 0 }, { 0, 2, 0, 1 },
- { 0, 2, 0, 2 }, { 0, 2, 1, 0 }, { 0, 2, 1, 1 }, { 0, 2, 1, 2 },
- { 0, 2, 2, 0 }, { 0, 2, 2, 1 }, { 0, 2, 2, 2 }, { 1, 0, 0, 0 },
- { 1, 0, 0, 1 }, { 1, 0, 0, 2 }, { 1, 0, 1, 0 }, { 1, 0, 1, 1 },
- { 1, 0, 1, 2 }, { 1, 0, 2, 0 }, { 1, 0, 2, 1 }, { 1, 0, 2, 2 },
- { 1, 1, 0, 0 }, { 1, 1, 0, 1 }, { 1, 1, 0, 2 }, { 1, 1, 1, 0 },
- { 1, 1, 1, 1 }, { 1, 1, 1, 2 }, { 1, 1, 2, 0 }, { 1, 1, 2, 1 },
- { 1, 1, 2, 2 }, { 1, 2, 0, 0 }, { 1, 2, 0, 1 }, { 1, 2, 0, 2 },
- { 1, 2, 1, 0 }, { 1, 2, 1, 1 }, { 1, 2, 1, 2 }, { 1, 2, 2, 0 },
- { 1, 2, 2, 1 }, { 1, 2, 2, 2 }, { 2, 0, 0, 0 }, { 2, 0, 0, 1 },
- { 2, 0, 0, 2 }, { 2, 0, 1, 0 }, { 2, 0, 1, 1 }, { 2, 0, 1, 2 },
- { 2, 0, 2, 0 }, { 2, 0, 2, 1 }, { 2, 0, 2, 2 }, { 2, 1, 0, 0 },
- { 2, 1, 0, 1 }, { 2, 1, 0, 2 }, { 2, 1, 1, 0 }, { 2, 1, 1, 1 },
- { 2, 1, 1, 2 }, { 2, 1, 2, 0 }, { 2, 1, 2, 1 }, { 2, 1, 2, 2 },
- { 2, 2, 0, 0 }, { 2, 2, 0, 1 }, { 2, 2, 0, 2 }, { 2, 2, 1, 0 },
- { 2, 2, 1, 1 }, { 2, 2, 1, 2 }, { 2, 2, 2, 0 }, { 2, 2, 2, 1 },
- { 2, 2, 2, 2 }, { 3, 0, 0, 0 }, { 3, 0, 0, 1 }, { 3, 0, 0, 2 },
- { 3, 0, 1, 0 }, { 3, 0, 1, 1 }, { 3, 0, 1, 2 }, { 3, 0, 2, 0 },
- { 3, 0, 2, 1 }, { 3, 0, 2, 2 }, { 3, 1, 0, 0 }, { 3, 1, 0, 1 },
- { 3, 1, 0, 2 }, { 3, 1, 1, 0 }, { 3, 1, 1, 1 }, { 3, 1, 1, 2 },
- { 3, 1, 2, 0 }, { 3, 1, 2, 1 }, { 3, 1, 2, 2 }, { 3, 2, 0, 0 },
- { 3, 2, 0, 1 }, { 3, 2, 0, 2 }, { 3, 2, 1, 0 }, { 3, 2, 1, 1 },
- { 3, 2, 1, 2 }, { 3, 2, 2, 0 }, { 3, 2, 2, 1 }, { 3, 2, 2, 2 },
-};
-
#define MODE2_PATTERNS_NUM 20
/**
* Intra types table
@@ -116,114 +65,4 @@ static const uint8_t rv40_luma_quant[2][
16, 17, 18, 19, 20, 20, 21, 21, 22, 23, 23, 23, 24, 24, 24, 24 }
};
-/**
- * Chroma quantizer values
- * Second table is used for DC-only blocks
- */
-static const uint8_t rv34_chroma_quant[2][32] = {
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25 },
- { 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 15, 16, 17, 18, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23 }
-};
-
-/**
- * This table is used for dequantizing
- */
-static const uint16_t rv34_qscale_tab[32] = {
- 60, 67, 76, 85, 96, 108, 121, 136,
- 152, 171, 192, 216, 242, 272, 305, 341,
- 383, 432, 481, 544, 606, 683, 767, 854,
- 963, 1074, 1212, 1392, 1566, 1708, 1978, 2211
-};
-
-/**
- * 4x4 dezigzag pattern
- */
-static const uint8_t rv34_dezigzag[16] = {
- 0, 1, 8, 16,
- 9, 2, 3, 10,
- 17, 24, 25, 18,
- 11, 19, 26, 27
-};
-
-/**
- * Tables used to translate quantizer value into VLC set for decoding
- * First table is used for intraframes.
- */
-static const uint8_t rv34_quant_to_vlc_set[2][31] = {
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
- 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3,
- 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6 },
-};
-
-/**
- * Table for obtaining quantizer difference
- */
-static const int8_t rv34_dquant_tab[] = {
- 0, 0, 2, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1,
- -1, 1, -1, 1, -1, 1, -2, 2, -2, 2, -2, 2, -2, 2, -2, 2,
- -2, 2, -2, 2, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3, -3, 3,
- -3, 3, -3, 3, -3, 3, -3, 3, -3, 3, -3, 2, -3, 1, -3, -5
-};
-
-/**
- * Maximum number of macroblocks for each of the possible slice offset sizes
- * @todo this is the same as ff_mba_max, maybe use it instead
- */
-static const uint16_t rv34_mb_max_sizes[6] = { 0x2F, 0x68, 0x18B, 0x62F, 0x18BF, 0x23FF };
-/**
- * Bits needed to code slice offset for the given size
- * @todo this is the same as ff_mba_length, maybe use it instead
- */
-static const uint8_t rv34_mb_bits_sizes[6] = { 6, 7, 9, 11, 13, 14 };
-
-/**
- * Dither values for deblocking filter - left/top values
- */
-static const uint8_t rv34_dither_l[16] = {
- 0x40, 0x50, 0x20, 0x60, 0x30, 0x50, 0x40, 0x30,
- 0x50, 0x40, 0x50, 0x30, 0x60, 0x20, 0x50, 0x40
-};
-/**
- * Dither values for deblocking filter - right/bottom values
- */
-static const uint8_t rv34_dither_r[16] = {
- 0x40, 0x30, 0x60, 0x20, 0x50, 0x30, 0x30, 0x40,
- 0x40, 0x40, 0x50, 0x30, 0x20, 0x60, 0x30, 0x40
-};
-
-/**
- * @begingroup loopfilter coefficients used by RV40 loop filter
- * @{
- */
-/** alpha parameter for RV40 loop filter - almost the same as in JVT-A003r1 */
-static const uint8_t rv34_alpha_tab[32] = {
- 128, 128, 128, 128, 128, 128, 128, 128,
- 128, 128, 122, 96, 75, 59, 47, 37,
- 29, 23, 18, 15, 13, 11, 10, 9,
- 8, 7, 6, 5, 4, 3, 2, 1
-};
-/** beta parameter for RV40 loop filter - almost the same as in JVT-A003r1 */
-static const uint8_t rv34_beta_tab[32] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 4, 4, 6, 6,
- 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14, 15, 16, 17
-};
-/** clip table for RV40 loop filter - the same as in JVT-A003r1 */
-static const uint8_t rv34_filter_clip_tbl[3][32] = {
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 7, 8, 9
- }
-};
-/** @} */ // end loopfilter group
#endif /* RV40DATA_H */
More information about the FFmpeg-soc
mailing list