• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/rv34.c

Go to the documentation of this file.
00001 /*
00002  * RV30/40 decoder common data
00003  * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #include "avcodec.h"
00028 #include "dsputil.h"
00029 #include "mpegvideo.h"
00030 #include "golomb.h"
00031 #include "mathops.h"
00032 #include "rectangle.h"
00033 
00034 #include "rv34vlc.h"
00035 #include "rv34data.h"
00036 #include "rv34.h"
00037 
00038 //#define DEBUG
00039 
00040 static inline void ZERO8x2(void* dst, int stride)
00041 {
00042     fill_rectangle(dst,                 1, 2, stride, 0, 4);
00043     fill_rectangle(((uint8_t*)(dst))+4, 1, 2, stride, 0, 4);
00044 }
00045 
00047 static const int rv34_mb_type_to_lavc[12] = {
00048     MB_TYPE_INTRA,
00049     MB_TYPE_INTRA16x16              | MB_TYPE_SEPARATE_DC,
00050     MB_TYPE_16x16   | MB_TYPE_L0,
00051     MB_TYPE_8x8     | MB_TYPE_L0,
00052     MB_TYPE_16x16   | MB_TYPE_L0,
00053     MB_TYPE_16x16   | MB_TYPE_L1,
00054     MB_TYPE_SKIP,
00055     MB_TYPE_DIRECT2 | MB_TYPE_16x16,
00056     MB_TYPE_16x8    | MB_TYPE_L0,
00057     MB_TYPE_8x16    | MB_TYPE_L0,
00058     MB_TYPE_16x16   | MB_TYPE_L0L1,
00059     MB_TYPE_16x16   | MB_TYPE_L0    | MB_TYPE_SEPARATE_DC
00060 };
00061 
00062 
00063 static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];
00064 
00070 static const int table_offs[] = {
00071       0,   1818,   3622,   4144,   4698,   5234,   5804,   5868,   5900,   5932,
00072    5996,   6252,   6316,   6348,   6380,   7674,   8944,  10274,  11668,  12250,
00073   14060,  15846,  16372,  16962,  17512,  18148,  18180,  18212,  18244,  18308,
00074   18564,  18628,  18660,  18692,  20036,  21314,  22648,  23968,  24614,  26384,
00075   28190,  28736,  29366,  29938,  30608,  30640,  30672,  30704,  30768,  31024,
00076   31088,  31120,  31184,  32570,  33898,  35236,  36644,  37286,  39020,  40802,
00077   41368,  42052,  42692,  43348,  43380,  43412,  43444,  43476,  43604,  43668,
00078   43700,  43732,  45100,  46430,  47778,  49160,  49802,  51550,  53340,  53972,
00079   54648,  55348,  55994,  56122,  56154,  56186,  56218,  56346,  56410,  56442,
00080   56474,  57878,  59290,  60636,  62036,  62682,  64460,  64524,  64588,  64716,
00081   64844,  66076,  67466,  67978,  68542,  69064,  69648,  70296,  72010,  72074,
00082   72138,  72202,  72330,  73572,  74936,  75454,  76030,  76566,  77176,  77822,
00083   79582,  79646,  79678,  79742,  79870,  81180,  82536,  83064,  83672,  84242,
00084   84934,  85576,  87384,  87448,  87480,  87544,  87672,  88982,  90340,  90902,
00085   91598,  92182,  92846,  93488,  95246,  95278,  95310,  95374,  95502,  96878,
00086   98266,  98848,  99542, 100234, 100884, 101524, 103320, 103352, 103384, 103416,
00087  103480, 104874, 106222, 106910, 107584, 108258, 108902, 109544, 111366, 111398,
00088  111430, 111462, 111494, 112878, 114320, 114988, 115660, 116310, 116950, 117592
00089 };
00090 
00091 static VLC_TYPE table_data[117592][2];
00092 
00101 static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms,
00102                          const int num)
00103 {
00104     int i;
00105     int counts[17] = {0}, codes[17];
00106     uint16_t cw[size], syms[size];
00107     uint8_t bits2[size];
00108     int maxbits = 0, realsize = 0;
00109 
00110     for(i = 0; i < size; i++){
00111         if(bits[i]){
00112             bits2[realsize] = bits[i];
00113             syms[realsize] = insyms ? insyms[i] : i;
00114             realsize++;
00115             maxbits = FFMAX(maxbits, bits[i]);
00116             counts[bits[i]]++;
00117         }
00118     }
00119 
00120     codes[0] = 0;
00121     for(i = 0; i < 16; i++)
00122         codes[i+1] = (codes[i] + counts[i]) << 1;
00123     for(i = 0; i < realsize; i++)
00124         cw[i] = codes[bits2[i]]++;
00125 
00126     vlc->table = &table_data[table_offs[num]];
00127     vlc->table_allocated = table_offs[num + 1] - table_offs[num];
00128     init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize,
00129                     bits2, 1, 1,
00130                     cw,    2, 2,
00131                     syms,  2, 2, INIT_VLC_USE_NEW_STATIC);
00132 }
00133 
00137 static av_cold void rv34_init_tables(void)
00138 {
00139     int i, j, k;
00140 
00141     for(i = 0; i < NUM_INTRA_TABLES; i++){
00142         for(j = 0; j < 2; j++){
00143             rv34_gen_vlc(rv34_table_intra_cbppat   [i][j], CBPPAT_VLC_SIZE,   &intra_vlcs[i].cbppattern[j],     NULL, 19*i + 0 + j);
00144             rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j], NULL, 19*i + 2 + j);
00145             rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j],  NULL, 19*i + 4 + j);
00146             for(k = 0; k < 4; k++){
00147                 rv34_gen_vlc(rv34_table_intra_cbp[i][j+k*2],  CBP_VLC_SIZE,   &intra_vlcs[i].cbp[j][k],         rv34_cbp_code, 19*i + 6 + j*4 + k);
00148             }
00149         }
00150         for(j = 0; j < 4; j++){
00151             rv34_gen_vlc(rv34_table_intra_firstpat[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j], NULL, 19*i + 14 + j);
00152         }
00153         rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL, 19*i + 18);
00154     }
00155 
00156     for(i = 0; i < NUM_INTER_TABLES; i++){
00157         rv34_gen_vlc(rv34_inter_cbppat[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0], NULL, i*12 + 95);
00158         for(j = 0; j < 4; j++){
00159             rv34_gen_vlc(rv34_inter_cbp[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j], rv34_cbp_code, i*12 + 96 + j);
00160         }
00161         for(j = 0; j < 2; j++){
00162             rv34_gen_vlc(rv34_table_inter_firstpat [i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j],  NULL, i*12 + 100 + j);
00163             rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j], NULL, i*12 + 102 + j);
00164             rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j],  NULL, i*12 + 104 + j);
00165         }
00166         rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL, i*12 + 106);
00167     }
00168 }
00169  // vlc group
00171 
00172 
00178 static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block)
00179 {
00180     int i;
00181 
00182     for(i=0; i<4; i++){
00183         const int z0= 13*(block[i+8*0] +    block[i+8*2]);
00184         const int z1= 13*(block[i+8*0] -    block[i+8*2]);
00185         const int z2=  7* block[i+8*1] - 17*block[i+8*3];
00186         const int z3= 17* block[i+8*1] +  7*block[i+8*3];
00187 
00188         temp[4*i+0]= z0+z3;
00189         temp[4*i+1]= z1+z2;
00190         temp[4*i+2]= z1-z2;
00191         temp[4*i+3]= z0-z3;
00192     }
00193 }
00194 
00199 static void rv34_inv_transform(DCTELEM *block){
00200     int temp[16];
00201     int i;
00202 
00203     rv34_row_transform(temp, block);
00204 
00205     for(i=0; i<4; i++){
00206         const int z0= 13*(temp[4*0+i] +    temp[4*2+i]) + 0x200;
00207         const int z1= 13*(temp[4*0+i] -    temp[4*2+i]) + 0x200;
00208         const int z2=  7* temp[4*1+i] - 17*temp[4*3+i];
00209         const int z3= 17* temp[4*1+i] +  7*temp[4*3+i];
00210 
00211         block[i*8+0]= (z0 + z3)>>10;
00212         block[i*8+1]= (z1 + z2)>>10;
00213         block[i*8+2]= (z1 - z2)>>10;
00214         block[i*8+3]= (z0 - z3)>>10;
00215     }
00216 
00217 }
00218 
00225 static void rv34_inv_transform_noround(DCTELEM *block){
00226     int temp[16];
00227     int i;
00228 
00229     rv34_row_transform(temp, block);
00230 
00231     for(i=0; i<4; i++){
00232         const int z0= 13*(temp[4*0+i] +    temp[4*2+i]);
00233         const int z1= 13*(temp[4*0+i] -    temp[4*2+i]);
00234         const int z2=  7* temp[4*1+i] - 17*temp[4*3+i];
00235         const int z3= 17* temp[4*1+i] +  7*temp[4*3+i];
00236 
00237         block[i*8+0]= ((z0 + z3)*3)>>11;
00238         block[i*8+1]= ((z1 + z2)*3)>>11;
00239         block[i*8+2]= ((z1 - z2)*3)>>11;
00240         block[i*8+3]= ((z0 - z3)*3)>>11;
00241     }
00242 
00243 }
00244  // transform
00246 
00247 
00256 static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table)
00257 {
00258     int pattern, code, cbp=0;
00259     int ones;
00260     static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000};
00261     static const int shifts[4] = { 0, 2, 8, 10 };
00262     const int *curshift = shifts;
00263     int i, t, mask;
00264 
00265     code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2);
00266     pattern = code & 0xF;
00267     code >>= 4;
00268 
00269     ones = rv34_count_ones[pattern];
00270 
00271     for(mask = 8; mask; mask >>= 1, curshift++){
00272         if(pattern & mask)
00273             cbp |= get_vlc2(gb, vlc->cbp[table][ones].table, vlc->cbp[table][ones].bits, 1) << curshift[0];
00274     }
00275 
00276     for(i = 0; i < 4; i++){
00277         t = modulo_three_table[code][i];
00278         if(t == 1)
00279             cbp |= cbp_masks[get_bits1(gb)] << i;
00280         if(t == 2)
00281             cbp |= cbp_masks[2] << i;
00282     }
00283     return cbp;
00284 }
00285 
00289 static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc)
00290 {
00291     if(coef){
00292         if(coef == esc){
00293             coef = get_vlc2(gb, vlc->table, 9, 2);
00294             if(coef > 23){
00295                 coef -= 23;
00296                 coef = 22 + ((1 << coef) | get_bits(gb, coef));
00297             }
00298             coef += esc;
00299         }
00300         if(get_bits1(gb))
00301             coef = -coef;
00302         *dst = coef;
00303     }
00304 }
00305 
00309 static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc)
00310 {
00311     int coeffs[4];
00312 
00313     coeffs[0] = modulo_three_table[code][0];
00314     coeffs[1] = modulo_three_table[code][1];
00315     coeffs[2] = modulo_three_table[code][2];
00316     coeffs[3] = modulo_three_table[code][3];
00317     decode_coeff(dst  , coeffs[0], 3, gb, vlc);
00318     if(is_block2){
00319         decode_coeff(dst+8, coeffs[1], 2, gb, vlc);
00320         decode_coeff(dst+1, coeffs[2], 2, gb, vlc);
00321     }else{
00322         decode_coeff(dst+1, coeffs[1], 2, gb, vlc);
00323         decode_coeff(dst+8, coeffs[2], 2, gb, vlc);
00324     }
00325     decode_coeff(dst+9, coeffs[3], 2, gb, vlc);
00326 }
00327 
00339 static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc)
00340 {
00341     int code, pattern;
00342 
00343     code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2);
00344 
00345     pattern = code & 0x7;
00346 
00347     code >>= 3;
00348     decode_subblock(dst, code, 0, gb, &rvlc->coefficient);
00349 
00350     if(pattern & 4){
00351         code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
00352         decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient);
00353     }
00354     if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block
00355         code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
00356         decode_subblock(dst + 8*2, code, 1, gb, &rvlc->coefficient);
00357     }
00358     if(pattern & 1){
00359         code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
00360         decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient);
00361     }
00362 
00363 }
00364 
00369 static inline void rv34_dequant4x4(DCTELEM *block, int Qdc, int Q)
00370 {
00371     int i, j;
00372 
00373     block[0] = (block[0] * Qdc + 8) >> 4;
00374     for(i = 0; i < 4; i++)
00375         for(j = !i; j < 4; j++)
00376             block[j + i*8] = (block[j + i*8] * Q + 8) >> 4;
00377 }
00378 
00383 static inline void rv34_dequant4x4_16x16(DCTELEM *block, int Qdc, int Q)
00384 {
00385     int i;
00386 
00387     for(i = 0; i < 3; i++)
00388          block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Qdc + 8) >> 4;
00389     for(; i < 16; i++)
00390          block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Q + 8) >> 4;
00391 } //block functions
00393 
00394 
00404 int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size)
00405 {
00406     int i;
00407     for(i = 0; i < 5; i++)
00408         if(rv34_mb_max_sizes[i] >= mb_size - 1)
00409             break;
00410     return rv34_mb_bits_sizes[i];
00411 }
00412 
00416 static inline RV34VLC* choose_vlc_set(int quant, int mod, int type)
00417 {
00418     if(mod == 2 && quant < 19) quant += 10;
00419     else if(mod && quant < 26) quant += 5;
00420     return type ? &inter_vlcs[rv34_quant_to_vlc_set[1][av_clip(quant, 0, 30)]]
00421                 : &intra_vlcs[rv34_quant_to_vlc_set[0][av_clip(quant, 0, 30)]];
00422 }
00423 
00427 static inline int rv34_decode_dquant(GetBitContext *gb, int quant)
00428 {
00429     if(get_bits1(gb))
00430         return rv34_dquant_tab[get_bits1(gb)][quant];
00431     else
00432         return get_bits(gb, 5);
00433 }
00434  //bitstream functions
00436 
00443 static const uint8_t part_sizes_w[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2 };
00444 
00446 static const uint8_t part_sizes_h[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2 };
00447 
00449 static const uint8_t avail_indexes[4] = { 6, 7, 10, 11 };
00450 
00458 static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int dmv_no)
00459 {
00460     MpegEncContext *s = &r->s;
00461     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00462     int A[2] = {0}, B[2], C[2];
00463     int i, j;
00464     int mx, my;
00465     int avail_index = avail_indexes[subblock_no];
00466     int c_off = part_sizes_w[block_type];
00467 
00468     mv_pos += (subblock_no & 1) + (subblock_no >> 1)*s->b8_stride;
00469     if(subblock_no == 3)
00470         c_off = -1;
00471 
00472     if(r->avail_cache[avail_index - 1]){
00473         A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0];
00474         A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1];
00475     }
00476     if(r->avail_cache[avail_index - 4]){
00477         B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0];
00478         B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1];
00479     }else{
00480         B[0] = A[0];
00481         B[1] = A[1];
00482     }
00483     if(!r->avail_cache[avail_index - 4 + c_off]){
00484         if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1] || r->rv30)){
00485             C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0];
00486             C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1];
00487         }else{
00488             C[0] = A[0];
00489             C[1] = A[1];
00490         }
00491     }else{
00492         C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][0];
00493         C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][1];
00494     }
00495     mx = mid_pred(A[0], B[0], C[0]);
00496     my = mid_pred(A[1], B[1], C[1]);
00497     mx += r->dmv[dmv_no][0];
00498     my += r->dmv[dmv_no][1];
00499     for(j = 0; j < part_sizes_h[block_type]; j++){
00500         for(i = 0; i < part_sizes_w[block_type]; i++){
00501             s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
00502             s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
00503         }
00504     }
00505 }
00506 
00507 #define GET_PTS_DIFF(a, b) ((a - b + 8192) & 0x1FFF)
00508 
00512 static int calc_add_mv(RV34DecContext *r, int dir, int val)
00513 {
00514     int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
00515     int dist = dir ? -GET_PTS_DIFF(r->next_pts, r->cur_pts) : GET_PTS_DIFF(r->cur_pts, r->last_pts);
00516     int mul;
00517 
00518     if(!refdist) return 0;
00519     mul = (dist << 14) / refdist;
00520     return (val * mul + 0x2000) >> 14;
00521 }
00522 
00526 static inline void rv34_pred_b_vector(int A[2], int B[2], int C[2],
00527                                       int A_avail, int B_avail, int C_avail,
00528                                       int *mx, int *my)
00529 {
00530     if(A_avail + B_avail + C_avail != 3){
00531         *mx = A[0] + B[0] + C[0];
00532         *my = A[1] + B[1] + C[1];
00533         if(A_avail + B_avail + C_avail == 2){
00534             *mx /= 2;
00535             *my /= 2;
00536         }
00537     }else{
00538         *mx = mid_pred(A[0], B[0], C[0]);
00539         *my = mid_pred(A[1], B[1], C[1]);
00540     }
00541 }
00542 
00546 static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
00547 {
00548     MpegEncContext *s = &r->s;
00549     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
00550     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00551     int A[2], B[2], C[2];
00552     int has_A = 0, has_B = 0, has_C = 0;
00553     int mx, my;
00554     int i, j;
00555     Picture *cur_pic = s->current_picture_ptr;
00556     const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0;
00557     int type = cur_pic->mb_type[mb_pos];
00558 
00559     memset(A, 0, sizeof(A));
00560     memset(B, 0, sizeof(B));
00561     memset(C, 0, sizeof(C));
00562     if((r->avail_cache[6-1] & type) & mask){
00563         A[0] = cur_pic->motion_val[dir][mv_pos - 1][0];
00564         A[1] = cur_pic->motion_val[dir][mv_pos - 1][1];
00565         has_A = 1;
00566     }
00567     if((r->avail_cache[6-4] & type) & mask){
00568         B[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][0];
00569         B[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][1];
00570         has_B = 1;
00571     }
00572     if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){
00573         C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][0];
00574         C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][1];
00575         has_C = 1;
00576     }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){
00577         C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][0];
00578         C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][1];
00579         has_C = 1;
00580     }
00581 
00582     rv34_pred_b_vector(A, B, C, has_A, has_B, has_C, &mx, &my);
00583 
00584     mx += r->dmv[dir][0];
00585     my += r->dmv[dir][1];
00586 
00587     for(j = 0; j < 2; j++){
00588         for(i = 0; i < 2; i++){
00589             cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
00590             cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
00591         }
00592     }
00593     if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){
00594         ZERO8x2(cur_pic->motion_val[!dir][mv_pos], s->b8_stride);
00595     }
00596 }
00597 
00601 static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
00602 {
00603     MpegEncContext *s = &r->s;
00604     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00605     int A[2] = {0}, B[2], C[2];
00606     int i, j, k;
00607     int mx, my;
00608     int avail_index = avail_indexes[0];
00609 
00610     if(r->avail_cache[avail_index - 1]){
00611         A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0];
00612         A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1];
00613     }
00614     if(r->avail_cache[avail_index - 4]){
00615         B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0];
00616         B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1];
00617     }else{
00618         B[0] = A[0];
00619         B[1] = A[1];
00620     }
00621     if(!r->avail_cache[avail_index - 4 + 2]){
00622         if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1])){
00623             C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0];
00624             C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1];
00625         }else{
00626             C[0] = A[0];
00627             C[1] = A[1];
00628         }
00629     }else{
00630         C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+2][0];
00631         C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+2][1];
00632     }
00633     mx = mid_pred(A[0], B[0], C[0]);
00634     my = mid_pred(A[1], B[1], C[1]);
00635     mx += r->dmv[0][0];
00636     my += r->dmv[0][1];
00637     for(j = 0; j < 2; j++){
00638         for(i = 0; i < 2; i++){
00639             for(k = 0; k < 2; k++){
00640                 s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
00641                 s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
00642             }
00643         }
00644     }
00645 }
00646 
00647 static const int chroma_coeffs[3] = { 0, 3, 5 };
00648 
00664 static inline void rv34_mc(RV34DecContext *r, const int block_type,
00665                           const int xoff, const int yoff, int mv_off,
00666                           const int width, const int height, int dir,
00667                           const int thirdpel,
00668                           qpel_mc_func (*qpel_mc)[16],
00669                           h264_chroma_mc_func (*chroma_mc))
00670 {
00671     MpegEncContext *s = &r->s;
00672     uint8_t *Y, *U, *V, *srcY, *srcU, *srcV;
00673     int dxy, mx, my, umx, umy, lx, ly, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
00674     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + mv_off;
00675     int is16x16 = 1;
00676 
00677     if(thirdpel){
00678         int chroma_mx, chroma_my;
00679         mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
00680         my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
00681         lx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
00682         ly = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
00683         chroma_mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + 1) >> 1;
00684         chroma_my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + 1) >> 1;
00685         umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24);
00686         umy = (chroma_my + (3 << 24)) / 3 - (1 << 24);
00687         uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3];
00688         uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3];
00689     }else{
00690         int cx, cy;
00691         mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] >> 2;
00692         my = s->current_picture_ptr->motion_val[dir][mv_pos][1] >> 2;
00693         lx = s->current_picture_ptr->motion_val[dir][mv_pos][0] & 3;
00694         ly = s->current_picture_ptr->motion_val[dir][mv_pos][1] & 3;
00695         cx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
00696         cy = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
00697         umx = cx >> 2;
00698         umy = cy >> 2;
00699         uvmx = (cx & 3) << 1;
00700         uvmy = (cy & 3) << 1;
00701         //due to some flaw RV40 uses the same MC compensation routine for H2V2 and H3V3
00702         if(uvmx == 6 && uvmy == 6)
00703             uvmx = uvmy = 4;
00704     }
00705     dxy = ly*4 + lx;
00706     srcY = dir ? s->next_picture_ptr->data[0] : s->last_picture_ptr->data[0];
00707     srcU = dir ? s->next_picture_ptr->data[1] : s->last_picture_ptr->data[1];
00708     srcV = dir ? s->next_picture_ptr->data[2] : s->last_picture_ptr->data[2];
00709     src_x = s->mb_x * 16 + xoff + mx;
00710     src_y = s->mb_y * 16 + yoff + my;
00711     uvsrc_x = s->mb_x * 8 + (xoff >> 1) + umx;
00712     uvsrc_y = s->mb_y * 8 + (yoff >> 1) + umy;
00713     srcY += src_y * s->linesize + src_x;
00714     srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
00715     srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
00716     if(   (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4
00717        || (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4){
00718         uint8_t *uvbuf= s->edge_emu_buffer + 22 * s->linesize;
00719 
00720         srcY -= 2 + 2*s->linesize;
00721         ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6,
00722                             src_x - 2, src_y - 2, s->h_edge_pos, s->v_edge_pos);
00723         srcY = s->edge_emu_buffer + 2 + 2*s->linesize;
00724         ff_emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1,
00725                             uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
00726         ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1,
00727                             uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
00728         srcU = uvbuf;
00729         srcV = uvbuf + 16;
00730     }
00731     Y = s->dest[0] + xoff      + yoff     *s->linesize;
00732     U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
00733     V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
00734 
00735     if(block_type == RV34_MB_P_16x8){
00736         qpel_mc[1][dxy](Y, srcY, s->linesize);
00737         Y    += 8;
00738         srcY += 8;
00739     }else if(block_type == RV34_MB_P_8x16){
00740         qpel_mc[1][dxy](Y, srcY, s->linesize);
00741         Y    += 8 * s->linesize;
00742         srcY += 8 * s->linesize;
00743     }
00744     is16x16 = (block_type != RV34_MB_P_8x8) && (block_type != RV34_MB_P_16x8) && (block_type != RV34_MB_P_8x16);
00745     qpel_mc[!is16x16][dxy](Y, srcY, s->linesize);
00746     chroma_mc[2-width]   (U, srcU, s->uvlinesize, height*4, uvmx, uvmy);
00747     chroma_mc[2-width]   (V, srcV, s->uvlinesize, height*4, uvmx, uvmy);
00748 }
00749 
00750 static void rv34_mc_1mv(RV34DecContext *r, const int block_type,
00751                         const int xoff, const int yoff, int mv_off,
00752                         const int width, const int height, int dir)
00753 {
00754     rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30,
00755             r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
00756                     : r->s.dsp.put_rv40_qpel_pixels_tab,
00757             r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
00758                     : r->s.dsp.put_rv40_chroma_pixels_tab);
00759 }
00760 
00761 static void rv34_mc_2mv(RV34DecContext *r, const int block_type)
00762 {
00763     rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30,
00764             r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
00765                     : r->s.dsp.put_rv40_qpel_pixels_tab,
00766             r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
00767                     : r->s.dsp.put_rv40_chroma_pixels_tab);
00768     rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30,
00769             r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab
00770                     : r->s.dsp.avg_rv40_qpel_pixels_tab,
00771             r->rv30 ? r->s.dsp.avg_h264_chroma_pixels_tab
00772                     : r->s.dsp.avg_rv40_chroma_pixels_tab);
00773 }
00774 
00775 static void rv34_mc_2mv_skip(RV34DecContext *r)
00776 {
00777     int i, j;
00778     for(j = 0; j < 2; j++)
00779         for(i = 0; i < 2; i++){
00780              rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30,
00781                     r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
00782                             : r->s.dsp.put_rv40_qpel_pixels_tab,
00783                     r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
00784                             : r->s.dsp.put_rv40_chroma_pixels_tab);
00785              rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30,
00786                     r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab
00787                             : r->s.dsp.avg_rv40_qpel_pixels_tab,
00788                     r->rv30 ? r->s.dsp.avg_h264_chroma_pixels_tab
00789                             : r->s.dsp.avg_rv40_chroma_pixels_tab);
00790         }
00791 }
00792 
00794 static const int num_mvs[RV34_MB_TYPES] = { 0, 0, 1, 4, 1, 1, 0, 0, 2, 2, 2, 1 };
00795 
00800 static int rv34_decode_mv(RV34DecContext *r, int block_type)
00801 {
00802     MpegEncContext *s = &r->s;
00803     GetBitContext *gb = &s->gb;
00804     int i, j, k, l;
00805     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00806     int next_bt;
00807 
00808     memset(r->dmv, 0, sizeof(r->dmv));
00809     for(i = 0; i < num_mvs[block_type]; i++){
00810         r->dmv[i][0] = svq3_get_se_golomb(gb);
00811         r->dmv[i][1] = svq3_get_se_golomb(gb);
00812     }
00813     switch(block_type){
00814     case RV34_MB_TYPE_INTRA:
00815     case RV34_MB_TYPE_INTRA16x16:
00816         ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00817         return 0;
00818     case RV34_MB_SKIP:
00819         if(s->pict_type == FF_P_TYPE){
00820             ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00821             rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
00822             break;
00823         }
00824     case RV34_MB_B_DIRECT:
00825         //surprisingly, it uses motion scheme from next reference frame
00826         next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride];
00827         if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){
00828             ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00829             ZERO8x2(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00830         }else
00831             for(j = 0; j < 2; j++)
00832                 for(i = 0; i < 2; i++)
00833                     for(k = 0; k < 2; k++)
00834                         for(l = 0; l < 2; l++)
00835                             s->current_picture_ptr->motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k]);
00836         if(!(IS_16X8(next_bt) || IS_8X16(next_bt) || IS_8X8(next_bt))) //we can use whole macroblock MC
00837             rv34_mc_2mv(r, block_type);
00838         else
00839             rv34_mc_2mv_skip(r);
00840         ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00841         break;
00842     case RV34_MB_P_16x16:
00843     case RV34_MB_P_MIX16x16:
00844         rv34_pred_mv(r, block_type, 0, 0);
00845         rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
00846         break;
00847     case RV34_MB_B_FORWARD:
00848     case RV34_MB_B_BACKWARD:
00849         r->dmv[1][0] = r->dmv[0][0];
00850         r->dmv[1][1] = r->dmv[0][1];
00851         if(r->rv30)
00852             rv34_pred_mv_rv3(r, block_type, block_type == RV34_MB_B_BACKWARD);
00853         else
00854             rv34_pred_mv_b  (r, block_type, block_type == RV34_MB_B_BACKWARD);
00855         rv34_mc_1mv     (r, block_type, 0, 0, 0, 2, 2, block_type == RV34_MB_B_BACKWARD);
00856         break;
00857     case RV34_MB_P_16x8:
00858     case RV34_MB_P_8x16:
00859         rv34_pred_mv(r, block_type, 0, 0);
00860         rv34_pred_mv(r, block_type, 1 + (block_type == RV34_MB_P_16x8), 1);
00861         if(block_type == RV34_MB_P_16x8){
00862             rv34_mc_1mv(r, block_type, 0, 0, 0,            2, 1, 0);
00863             rv34_mc_1mv(r, block_type, 0, 8, s->b8_stride, 2, 1, 0);
00864         }
00865         if(block_type == RV34_MB_P_8x16){
00866             rv34_mc_1mv(r, block_type, 0, 0, 0, 1, 2, 0);
00867             rv34_mc_1mv(r, block_type, 8, 0, 1, 1, 2, 0);
00868         }
00869         break;
00870     case RV34_MB_B_BIDIR:
00871         rv34_pred_mv_b  (r, block_type, 0);
00872         rv34_pred_mv_b  (r, block_type, 1);
00873         rv34_mc_2mv     (r, block_type);
00874         break;
00875     case RV34_MB_P_8x8:
00876         for(i=0;i< 4;i++){
00877             rv34_pred_mv(r, block_type, i, i);
00878             rv34_mc_1mv (r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1, 0);
00879         }
00880         break;
00881     }
00882 
00883     return 0;
00884 } // mv group
00886 
00892 static const int ittrans[9] = {
00893  DC_PRED, VERT_PRED, HOR_PRED, DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_LEFT_PRED,
00894  VERT_RIGHT_PRED, VERT_LEFT_PRED, HOR_UP_PRED, HOR_DOWN_PRED,
00895 };
00896 
00898 static const int ittrans16[4] = {
00899  DC_PRED8x8, VERT_PRED8x8, HOR_PRED8x8, PLANE_PRED8x8,
00900 };
00901 
00905 static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int itype, int up, int left, int down, int right)
00906 {
00907     uint8_t *prev = dst - stride + 4;
00908     uint32_t topleft;
00909 
00910     if(!up && !left)
00911         itype = DC_128_PRED;
00912     else if(!up){
00913         if(itype == VERT_PRED) itype = HOR_PRED;
00914         if(itype == DC_PRED)   itype = LEFT_DC_PRED;
00915     }else if(!left){
00916         if(itype == HOR_PRED)  itype = VERT_PRED;
00917         if(itype == DC_PRED)   itype = TOP_DC_PRED;
00918         if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
00919     }
00920     if(!down){
00921         if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
00922         if(itype == HOR_UP_PRED) itype = HOR_UP_PRED_RV40_NODOWN;
00923         if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN;
00924     }
00925     if(!right && up){
00926         topleft = dst[-stride + 3] * 0x01010101;
00927         prev = (uint8_t*)&topleft;
00928     }
00929     r->h.pred4x4[itype](dst, prev, stride);
00930 }
00931 
00933 static void rv34_add_4x4_block(uint8_t *dst, int stride, DCTELEM block[64], int off)
00934 {
00935     int x, y;
00936     for(y = 0; y < 4; y++)
00937         for(x = 0; x < 4; x++)
00938             dst[x + y*stride] = av_clip_uint8(dst[x + y*stride] + block[off + x+y*8]);
00939 }
00940 
00941 static inline int adjust_pred16(int itype, int up, int left)
00942 {
00943     if(!up && !left)
00944         itype = DC_128_PRED8x8;
00945     else if(!up){
00946         if(itype == PLANE_PRED8x8)itype = HOR_PRED8x8;
00947         if(itype == VERT_PRED8x8) itype = HOR_PRED8x8;
00948         if(itype == DC_PRED8x8)   itype = LEFT_DC_PRED8x8;
00949     }else if(!left){
00950         if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8;
00951         if(itype == HOR_PRED8x8)  itype = VERT_PRED8x8;
00952         if(itype == DC_PRED8x8)   itype = TOP_DC_PRED8x8;
00953     }
00954     return itype;
00955 }
00956 
00957 static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int cbp, int is16)
00958 {
00959     MpegEncContext *s = &r->s;
00960     DSPContext *dsp = &s->dsp;
00961     int i, j;
00962     uint8_t *Y, *U, *V;
00963     int itype;
00964     int avail[6*8] = {0};
00965     int idx;
00966 
00967     // Set neighbour information.
00968     if(r->avail_cache[1])
00969         avail[0] = 1;
00970     if(r->avail_cache[2])
00971         avail[1] = avail[2] = 1;
00972     if(r->avail_cache[3])
00973         avail[3] = avail[4] = 1;
00974     if(r->avail_cache[4])
00975         avail[5] = 1;
00976     if(r->avail_cache[5])
00977         avail[8] = avail[16] = 1;
00978     if(r->avail_cache[9])
00979         avail[24] = avail[32] = 1;
00980 
00981     Y = s->dest[0];
00982     U = s->dest[1];
00983     V = s->dest[2];
00984     if(!is16){
00985         for(j = 0; j < 4; j++){
00986             idx = 9 + j*8;
00987             for(i = 0; i < 4; i++, cbp >>= 1, Y += 4, idx++){
00988                 rv34_pred_4x4_block(r, Y, s->linesize, ittrans[intra_types[i]], avail[idx-8], avail[idx-1], avail[idx+7], avail[idx-7]);
00989                 avail[idx] = 1;
00990                 if(cbp & 1)
00991                     rv34_add_4x4_block(Y, s->linesize, s->block[(i>>1)+(j&2)], (i&1)*4+(j&1)*32);
00992             }
00993             Y += s->linesize * 4 - 4*4;
00994             intra_types += r->intra_types_stride;
00995         }
00996         intra_types -= r->intra_types_stride * 4;
00997         fill_rectangle(r->avail_cache + 6, 2, 2, 4, 0, 4);
00998         for(j = 0; j < 2; j++){
00999             idx = 6 + j*4;
01000             for(i = 0; i < 2; i++, cbp >>= 1, idx++){
01001                 rv34_pred_4x4_block(r, U + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*r->intra_types_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]);
01002                 rv34_pred_4x4_block(r, V + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*r->intra_types_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]);
01003                 r->avail_cache[idx] = 1;
01004                 if(cbp & 0x01)
01005                     rv34_add_4x4_block(U + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[4], i*4+j*32);
01006                 if(cbp & 0x10)
01007                     rv34_add_4x4_block(V + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[5], i*4+j*32);
01008             }
01009         }
01010     }else{
01011         itype = ittrans16[intra_types[0]];
01012         itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
01013         r->h.pred16x16[itype](Y, s->linesize);
01014         dsp->add_pixels_clamped(s->block[0], Y,     s->linesize);
01015         dsp->add_pixels_clamped(s->block[1], Y + 8, s->linesize);
01016         Y += s->linesize * 8;
01017         dsp->add_pixels_clamped(s->block[2], Y,     s->linesize);
01018         dsp->add_pixels_clamped(s->block[3], Y + 8, s->linesize);
01019 
01020         itype = ittrans16[intra_types[0]];
01021         if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
01022         itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
01023         r->h.pred8x8[itype](U, s->uvlinesize);
01024         dsp->add_pixels_clamped(s->block[4], U, s->uvlinesize);
01025         r->h.pred8x8[itype](V, s->uvlinesize);
01026         dsp->add_pixels_clamped(s->block[5], V, s->uvlinesize);
01027     }
01028 }
01029  // recons group
01031 
01036 static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types)
01037 {
01038     MpegEncContext *s = &r->s;
01039     GetBitContext *gb = &s->gb;
01040     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
01041     int i, t;
01042 
01043     if(!r->si.type){
01044         r->is16 = get_bits1(gb);
01045         if(!r->is16 && !r->rv30){
01046             if(!get_bits1(gb))
01047                 av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
01048         }
01049         s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA;
01050         r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA;
01051     }else{
01052         r->block_type = r->decode_mb_info(r);
01053         if(r->block_type == -1)
01054             return -1;
01055         s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
01056         r->mb_type[mb_pos] = r->block_type;
01057         if(r->block_type == RV34_MB_SKIP){
01058             if(s->pict_type == FF_P_TYPE)
01059                 r->mb_type[mb_pos] = RV34_MB_P_16x16;
01060             if(s->pict_type == FF_B_TYPE)
01061                 r->mb_type[mb_pos] = RV34_MB_B_DIRECT;
01062         }
01063         r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]);
01064         rv34_decode_mv(r, r->block_type);
01065         if(r->block_type == RV34_MB_SKIP){
01066             fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0]));
01067             return 0;
01068         }
01069         r->chroma_vlc = 1;
01070         r->luma_vlc   = 0;
01071     }
01072     if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
01073         if(r->is16){
01074             t = get_bits(gb, 2);
01075             fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
01076             r->luma_vlc   = 2;
01077         }else{
01078             if(r->decode_intra_types(r, gb, intra_types) < 0)
01079                 return -1;
01080             r->luma_vlc   = 1;
01081         }
01082         r->chroma_vlc = 0;
01083         r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
01084     }else{
01085         for(i = 0; i < 16; i++)
01086             intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0;
01087         r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
01088         if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){
01089             r->is16 = 1;
01090             r->chroma_vlc = 1;
01091             r->luma_vlc   = 2;
01092             r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
01093         }
01094     }
01095 
01096     return rv34_decode_cbp(gb, r->cur_vlcs, r->is16);
01097 }
01098 
01107 #define LUMA_CBP_BLOCK_MASK 0x33
01108 
01109 #define U_CBP_MASK 0x0F0000
01110 #define V_CBP_MASK 0xF00000
01111 
01112 
01113 static void rv34_apply_differences(RV34DecContext *r, int cbp)
01114 {
01115     static const int shifts[4] = { 0, 2, 8, 10 };
01116     MpegEncContext *s = &r->s;
01117     int i;
01118 
01119     for(i = 0; i < 4; i++)
01120         if((cbp & (LUMA_CBP_BLOCK_MASK << shifts[i])) || r->block_type == RV34_MB_P_MIX16x16)
01121             s->dsp.add_pixels_clamped(s->block[i], s->dest[0] + (i & 1)*8 + (i&2)*4*s->linesize, s->linesize);
01122     if(cbp & U_CBP_MASK)
01123         s->dsp.add_pixels_clamped(s->block[4], s->dest[1], s->uvlinesize);
01124     if(cbp & V_CBP_MASK)
01125         s->dsp.add_pixels_clamped(s->block[5], s->dest[2], s->uvlinesize);
01126 }
01127 
01128 static int is_mv_diff_gt_3(int16_t (*motion_val)[2], int step)
01129 {
01130     int d;
01131     d = motion_val[0][0] - motion_val[-step][0];
01132     if(d < -3 || d > 3)
01133         return 1;
01134     d = motion_val[0][1] - motion_val[-step][1];
01135     if(d < -3 || d > 3)
01136         return 1;
01137     return 0;
01138 }
01139 
01140 static int rv34_set_deblock_coef(RV34DecContext *r)
01141 {
01142     MpegEncContext *s = &r->s;
01143     int hmvmask = 0, vmvmask = 0, i, j;
01144     int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
01145     int16_t (*motion_val)[2] = s->current_picture_ptr->motion_val[0][midx];
01146     for(j = 0; j < 16; j += 8){
01147         for(i = 0; i < 2; i++){
01148             if(is_mv_diff_gt_3(motion_val + i, 1))
01149                 vmvmask |= 0x11 << (j + i*2);
01150             if((j || s->mb_y) && is_mv_diff_gt_3(motion_val + i, s->b8_stride))
01151                 hmvmask |= 0x03 << (j + i*2);
01152         }
01153         motion_val += s->b8_stride;
01154     }
01155     if(s->first_slice_line)
01156         hmvmask &= ~0x000F;
01157     if(!s->mb_x)
01158         vmvmask &= ~0x1111;
01159     if(r->rv30){ //RV30 marks both subblocks on the edge for filtering
01160         vmvmask |= (vmvmask & 0x4444) >> 1;
01161         hmvmask |= (hmvmask & 0x0F00) >> 4;
01162         if(s->mb_x)
01163             r->deblock_coefs[s->mb_x - 1 + s->mb_y*s->mb_stride] |= (vmvmask & 0x1111) << 3;
01164         if(!s->first_slice_line)
01165             r->deblock_coefs[s->mb_x + (s->mb_y - 1)*s->mb_stride] |= (hmvmask & 0xF) << 12;
01166     }
01167     return hmvmask | vmvmask;
01168 }
01169 
01170 static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
01171 {
01172     MpegEncContext *s = &r->s;
01173     GetBitContext *gb = &s->gb;
01174     int cbp, cbp2;
01175     int i, blknum, blkoff;
01176     DCTELEM block16[64];
01177     int luma_dc_quant;
01178     int dist;
01179     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
01180 
01181     // Calculate which neighbours are available. Maybe it's worth optimizing too.
01182     memset(r->avail_cache, 0, sizeof(r->avail_cache));
01183     fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4);
01184     dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
01185     if(s->mb_x && dist)
01186         r->avail_cache[5] =
01187         r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
01188     if(dist >= s->mb_width)
01189         r->avail_cache[2] =
01190         r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
01191     if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
01192         r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
01193     if(s->mb_x && dist > s->mb_width)
01194         r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];
01195 
01196     s->qscale = r->si.quant;
01197     cbp = cbp2 = rv34_decode_mb_header(r, intra_types);
01198     r->cbp_luma  [mb_pos] = cbp;
01199     r->cbp_chroma[mb_pos] = cbp >> 16;
01200     if(s->pict_type == FF_I_TYPE)
01201         r->deblock_coefs[mb_pos] = 0xFFFF;
01202     else
01203         r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos];
01204     s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;
01205 
01206     if(cbp == -1)
01207         return -1;
01208 
01209     luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16 ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale];
01210     if(r->is16){
01211         memset(block16, 0, sizeof(block16));
01212         rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0);
01213         rv34_dequant4x4_16x16(block16, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
01214         rv34_inv_transform_noround(block16);
01215     }
01216 
01217     for(i = 0; i < 16; i++, cbp >>= 1){
01218         if(!r->is16 && !(cbp & 1)) continue;
01219         blknum = ((i & 2) >> 1) + ((i & 8) >> 2);
01220         blkoff = ((i & 1) << 2) + ((i & 4) << 3);
01221         if(cbp & 1)
01222             rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0);
01223         rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[s->qscale],rv34_qscale_tab[s->qscale]);
01224         if(r->is16) //FIXME: optimize
01225             s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)];
01226         rv34_inv_transform(s->block[blknum] + blkoff);
01227     }
01228     if(r->block_type == RV34_MB_P_MIX16x16)
01229         r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
01230     for(; i < 24; i++, cbp >>= 1){
01231         if(!(cbp & 1)) continue;
01232         blknum = ((i & 4) >> 2) + 4;
01233         blkoff = ((i & 1) << 2) + ((i & 2) << 4);
01234         rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1);
01235         rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]);
01236         rv34_inv_transform(s->block[blknum] + blkoff);
01237     }
01238     if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos]))
01239         rv34_output_macroblock(r, intra_types, cbp2, r->is16);
01240     else
01241         rv34_apply_differences(r, cbp2);
01242 
01243     return 0;
01244 }
01245 
01246 static int check_slice_end(RV34DecContext *r, MpegEncContext *s)
01247 {
01248     int bits;
01249     if(s->mb_y >= s->mb_height)
01250         return 1;
01251     if(!s->mb_num_left)
01252         return 1;
01253     if(r->s.mb_skip_run > 1)
01254         return 0;
01255     bits = r->bits - get_bits_count(&s->gb);
01256     if(bits < 0 || (bits < 8 && !show_bits(&s->gb, bits)))
01257         return 1;
01258     return 0;
01259 }
01260 
01261 static inline int slice_compare(SliceInfo *si1, SliceInfo *si2)
01262 {
01263     return si1->type   != si2->type  ||
01264            si1->start  >= si2->start ||
01265            si1->width  != si2->width ||
01266            si1->height != si2->height||
01267            si1->pts    != si2->pts;
01268 }
01269 
01270 static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int buf_size)
01271 {
01272     MpegEncContext *s = &r->s;
01273     GetBitContext *gb = &s->gb;
01274     int mb_pos;
01275     int res;
01276 
01277     init_get_bits(&r->s.gb, buf, buf_size*8);
01278     res = r->parse_slice_header(r, gb, &r->si);
01279     if(res < 0){
01280         av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n");
01281         return -1;
01282     }
01283 
01284     if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
01285         if(s->width != r->si.width || s->height != r->si.height){
01286             av_log(s->avctx, AV_LOG_DEBUG, "Changing dimensions to %dx%d\n", r->si.width,r->si.height);
01287             MPV_common_end(s);
01288             s->width  = r->si.width;
01289             s->height = r->si.height;
01290             avcodec_set_dimensions(s->avctx, s->width, s->height);
01291             if(MPV_common_init(s) < 0)
01292                 return -1;
01293             r->intra_types_stride = s->mb_width*4 + 4;
01294             r->intra_types_hist = av_realloc(r->intra_types_hist, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
01295             r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;
01296             r->mb_type = av_realloc(r->mb_type, r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type));
01297             r->cbp_luma   = av_realloc(r->cbp_luma,   r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma));
01298             r->cbp_chroma = av_realloc(r->cbp_chroma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma));
01299             r->deblock_coefs = av_realloc(r->deblock_coefs, r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs));
01300         }
01301         s->pict_type = r->si.type ? r->si.type : FF_I_TYPE;
01302         if(MPV_frame_start(s, s->avctx) < 0)
01303             return -1;
01304         ff_er_frame_start(s);
01305         r->cur_pts = r->si.pts;
01306         if(s->pict_type != FF_B_TYPE){
01307             r->last_pts = r->next_pts;
01308             r->next_pts = r->cur_pts;
01309         }
01310         s->mb_x = s->mb_y = 0;
01311     }
01312 
01313     r->si.end = end;
01314     s->qscale = r->si.quant;
01315     r->bits = buf_size*8;
01316     s->mb_num_left = r->si.end - r->si.start;
01317     r->s.mb_skip_run = 0;
01318 
01319     mb_pos = s->mb_x + s->mb_y * s->mb_width;
01320     if(r->si.start != mb_pos){
01321         av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->si.start, mb_pos);
01322         s->mb_x = r->si.start % s->mb_width;
01323         s->mb_y = r->si.start / s->mb_width;
01324     }
01325     memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
01326     s->first_slice_line = 1;
01327     s->resync_mb_x= s->mb_x;
01328     s->resync_mb_y= s->mb_y;
01329 
01330     ff_init_block_index(s);
01331     while(!check_slice_end(r, s)) {
01332         ff_update_block_index(s);
01333         s->dsp.clear_blocks(s->block[0]);
01334 
01335         if(rv34_decode_macroblock(r, r->intra_types + s->mb_x * 4 + 4) < 0){
01336             ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_ERROR|DC_ERROR|MV_ERROR);
01337             return -1;
01338         }
01339         if (++s->mb_x == s->mb_width) {
01340             s->mb_x = 0;
01341             s->mb_y++;
01342             ff_init_block_index(s);
01343 
01344             memmove(r->intra_types_hist, r->intra_types, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));
01345             memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));
01346 
01347             if(r->loop_filter && s->mb_y >= 2)
01348                 r->loop_filter(r, s->mb_y - 2);
01349         }
01350         if(s->mb_x == s->resync_mb_x)
01351             s->first_slice_line=0;
01352         s->mb_num_left--;
01353     }
01354     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);
01355 
01356     return s->mb_y == s->mb_height;
01357 }
01358  // recons group end
01360 
01364 av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
01365 {
01366     RV34DecContext *r = avctx->priv_data;
01367     MpegEncContext *s = &r->s;
01368 
01369     MPV_decode_defaults(s);
01370     s->avctx= avctx;
01371     s->out_format = FMT_H263;
01372     s->codec_id= avctx->codec_id;
01373 
01374     s->width = avctx->width;
01375     s->height = avctx->height;
01376 
01377     r->s.avctx = avctx;
01378     avctx->flags |= CODEC_FLAG_EMU_EDGE;
01379     r->s.flags |= CODEC_FLAG_EMU_EDGE;
01380     avctx->pix_fmt = PIX_FMT_YUV420P;
01381     avctx->has_b_frames = 1;
01382     s->low_delay = 0;
01383 
01384     if (MPV_common_init(s) < 0)
01385         return -1;
01386 
01387     ff_h264_pred_init(&r->h, CODEC_ID_RV40);
01388 
01389     r->intra_types_stride = 4*s->mb_stride + 4;
01390     r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
01391     r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;
01392 
01393     r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type));
01394 
01395     r->cbp_luma   = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma));
01396     r->cbp_chroma = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma));
01397     r->deblock_coefs = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs));
01398 
01399     if(!intra_vlcs[0].cbppattern[0].bits)
01400         rv34_init_tables();
01401 
01402     return 0;
01403 }
01404 
01405 static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n)
01406 {
01407     if(avctx->slice_count) return avctx->slice_offset[n];
01408     else                   return AV_RL32(buf + n*8 - 4) == 1 ? AV_RL32(buf + n*8) :  AV_RB32(buf + n*8);
01409 }
01410 
01411 int ff_rv34_decode_frame(AVCodecContext *avctx,
01412                             void *data, int *data_size,
01413                             AVPacket *avpkt)
01414 {
01415     const uint8_t *buf = avpkt->data;
01416     int buf_size = avpkt->size;
01417     RV34DecContext *r = avctx->priv_data;
01418     MpegEncContext *s = &r->s;
01419     AVFrame *pict = data;
01420     SliceInfo si;
01421     int i;
01422     int slice_count;
01423     const uint8_t *slices_hdr = NULL;
01424     int last = 0;
01425 
01426     /* no supplementary picture */
01427     if (buf_size == 0) {
01428         /* special case for last picture */
01429         if (s->low_delay==0 && s->next_picture_ptr) {
01430             *pict= *(AVFrame*)s->next_picture_ptr;
01431             s->next_picture_ptr= NULL;
01432 
01433             *data_size = sizeof(AVFrame);
01434         }
01435         return 0;
01436     }
01437 
01438     if(!avctx->slice_count){
01439         slice_count = (*buf++) + 1;
01440         slices_hdr = buf + 4;
01441         buf += 8 * slice_count;
01442     }else
01443         slice_count = avctx->slice_count;
01444 
01445     //parse first slice header to check whether this frame can be decoded
01446     if(get_slice_offset(avctx, slices_hdr, 0) > buf_size){
01447         av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n");
01448         return -1;
01449     }
01450     init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), buf_size-get_slice_offset(avctx, slices_hdr, 0));
01451     if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){
01452         av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");
01453         return -1;
01454     }
01455     if((!s->last_picture_ptr || !s->last_picture_ptr->data[0]) && si.type == FF_B_TYPE)
01456         return -1;
01457     /* skip b frames if we are in a hurry */
01458     if(avctx->hurry_up && si.type==FF_B_TYPE) return buf_size;
01459     if(   (avctx->skip_frame >= AVDISCARD_NONREF && si.type==FF_B_TYPE)
01460        || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=FF_I_TYPE)
01461        ||  avctx->skip_frame >= AVDISCARD_ALL)
01462         return buf_size;
01463     /* skip everything if we are in a hurry>=5 */
01464     if(avctx->hurry_up>=5)
01465         return buf_size;
01466 
01467     for(i=0; i<slice_count; i++){
01468         int offset= get_slice_offset(avctx, slices_hdr, i);
01469         int size;
01470         if(i+1 == slice_count)
01471             size= buf_size - offset;
01472         else
01473             size= get_slice_offset(avctx, slices_hdr, i+1) - offset;
01474 
01475         if(offset > buf_size){
01476             av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n");
01477             break;
01478         }
01479 
01480         r->si.end = s->mb_width * s->mb_height;
01481         if(i+1 < slice_count){
01482             init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8);
01483             if(r->parse_slice_header(r, &r->s.gb, &si) < 0){
01484                 if(i+2 < slice_count)
01485                     size = get_slice_offset(avctx, slices_hdr, i+2) - offset;
01486                 else
01487                     size = buf_size - offset;
01488             }else
01489                 r->si.end = si.start;
01490         }
01491         last = rv34_decode_slice(r, r->si.end, buf + offset, size);
01492         s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;
01493         if(last)
01494             break;
01495     }
01496 
01497     if(last){
01498         if(r->loop_filter)
01499             r->loop_filter(r, s->mb_height - 1);
01500         ff_er_frame_end(s);
01501         MPV_frame_end(s);
01502         if (s->pict_type == FF_B_TYPE || s->low_delay) {
01503             *pict= *(AVFrame*)s->current_picture_ptr;
01504         } else if (s->last_picture_ptr != NULL) {
01505             *pict= *(AVFrame*)s->last_picture_ptr;
01506         }
01507 
01508         if(s->last_picture_ptr || s->low_delay){
01509             *data_size = sizeof(AVFrame);
01510             ff_print_debug_info(s, pict);
01511         }
01512         s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
01513     }
01514     return buf_size;
01515 }
01516 
01517 av_cold int ff_rv34_decode_end(AVCodecContext *avctx)
01518 {
01519     RV34DecContext *r = avctx->priv_data;
01520 
01521     MPV_common_end(&r->s);
01522 
01523     av_freep(&r->intra_types_hist);
01524     r->intra_types = NULL;
01525     av_freep(&r->mb_type);
01526     av_freep(&r->cbp_luma);
01527     av_freep(&r->cbp_chroma);
01528     av_freep(&r->deblock_coefs);
01529 
01530     return 0;
01531 }

Generated on Fri Sep 16 2011 17:17:42 for FFmpeg by  doxygen 1.7.1