00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
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 
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 
00065 static int rv34_decode_mv(RV34DecContext *r, int block_type);
00066 
00072 static const int table_offs[] = {
00073       0,   1818,   3622,   4144,   4698,   5234,   5804,   5868,   5900,   5932,
00074    5996,   6252,   6316,   6348,   6380,   7674,   8944,  10274,  11668,  12250,
00075   14060,  15846,  16372,  16962,  17512,  18148,  18180,  18212,  18244,  18308,
00076   18564,  18628,  18660,  18692,  20036,  21314,  22648,  23968,  24614,  26384,
00077   28190,  28736,  29366,  29938,  30608,  30640,  30672,  30704,  30768,  31024,
00078   31088,  31120,  31184,  32570,  33898,  35236,  36644,  37286,  39020,  40802,
00079   41368,  42052,  42692,  43348,  43380,  43412,  43444,  43476,  43604,  43668,
00080   43700,  43732,  45100,  46430,  47778,  49160,  49802,  51550,  53340,  53972,
00081   54648,  55348,  55994,  56122,  56154,  56186,  56218,  56346,  56410,  56442,
00082   56474,  57878,  59290,  60636,  62036,  62682,  64460,  64524,  64588,  64716,
00083   64844,  66076,  67466,  67978,  68542,  69064,  69648,  70296,  72010,  72074,
00084   72138,  72202,  72330,  73572,  74936,  75454,  76030,  76566,  77176,  77822,
00085   79582,  79646,  79678,  79742,  79870,  81180,  82536,  83064,  83672,  84242,
00086   84934,  85576,  87384,  87448,  87480,  87544,  87672,  88982,  90340,  90902,
00087   91598,  92182,  92846,  93488,  95246,  95278,  95310,  95374,  95502,  96878,
00088   98266,  98848,  99542, 100234, 100884, 101524, 103320, 103352, 103384, 103416,
00089  103480, 104874, 106222, 106910, 107584, 108258, 108902, 109544, 111366, 111398,
00090  111430, 111462, 111494, 112878, 114320, 114988, 115660, 116310, 116950, 117592
00091 };
00092 
00093 static VLC_TYPE table_data[117592][2];
00094 
00103 static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms,
00104                          const int num)
00105 {
00106     int i;
00107     int counts[17] = {0}, codes[17];
00108     uint16_t cw[MAX_VLC_SIZE], syms[MAX_VLC_SIZE];
00109     uint8_t bits2[MAX_VLC_SIZE];
00110     int maxbits = 0, realsize = 0;
00111 
00112     for(i = 0; i < size; i++){
00113         if(bits[i]){
00114             bits2[realsize] = bits[i];
00115             syms[realsize] = insyms ? insyms[i] : i;
00116             realsize++;
00117             maxbits = FFMAX(maxbits, bits[i]);
00118             counts[bits[i]]++;
00119         }
00120     }
00121 
00122     codes[0] = 0;
00123     for(i = 0; i < 16; i++)
00124         codes[i+1] = (codes[i] + counts[i]) << 1;
00125     for(i = 0; i < realsize; i++)
00126         cw[i] = codes[bits2[i]]++;
00127 
00128     vlc->table = &table_data[table_offs[num]];
00129     vlc->table_allocated = table_offs[num + 1] - table_offs[num];
00130     init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize,
00131                     bits2, 1, 1,
00132                     cw,    2, 2,
00133                     syms,  2, 2, INIT_VLC_USE_NEW_STATIC);
00134 }
00135 
00139 static av_cold void rv34_init_tables(void)
00140 {
00141     int i, j, k;
00142 
00143     for(i = 0; i < NUM_INTRA_TABLES; i++){
00144         for(j = 0; j < 2; j++){
00145             rv34_gen_vlc(rv34_table_intra_cbppat   [i][j], CBPPAT_VLC_SIZE,   &intra_vlcs[i].cbppattern[j],     NULL, 19*i + 0 + j);
00146             rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j], NULL, 19*i + 2 + j);
00147             rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j],  NULL, 19*i + 4 + j);
00148             for(k = 0; k < 4; k++){
00149                 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);
00150             }
00151         }
00152         for(j = 0; j < 4; j++){
00153             rv34_gen_vlc(rv34_table_intra_firstpat[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j], NULL, 19*i + 14 + j);
00154         }
00155         rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL, 19*i + 18);
00156     }
00157 
00158     for(i = 0; i < NUM_INTER_TABLES; i++){
00159         rv34_gen_vlc(rv34_inter_cbppat[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0], NULL, i*12 + 95);
00160         for(j = 0; j < 4; j++){
00161             rv34_gen_vlc(rv34_inter_cbp[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j], rv34_cbp_code, i*12 + 96 + j);
00162         }
00163         for(j = 0; j < 2; j++){
00164             rv34_gen_vlc(rv34_table_inter_firstpat [i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j],  NULL, i*12 + 100 + j);
00165             rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j], NULL, i*12 + 102 + j);
00166             rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j],  NULL, i*12 + 104 + j);
00167         }
00168         rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL, i*12 + 106);
00169     }
00170 }
00171  
00173 
00182 static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table)
00183 {
00184     int pattern, code, cbp=0;
00185     int ones;
00186     static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000};
00187     static const int shifts[4] = { 0, 2, 8, 10 };
00188     const int *curshift = shifts;
00189     int i, t, mask;
00190 
00191     code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2);
00192     pattern = code & 0xF;
00193     code >>= 4;
00194 
00195     ones = rv34_count_ones[pattern];
00196 
00197     for(mask = 8; mask; mask >>= 1, curshift++){
00198         if(pattern & mask)
00199             cbp |= get_vlc2(gb, vlc->cbp[table][ones].table, vlc->cbp[table][ones].bits, 1) << curshift[0];
00200     }
00201 
00202     for(i = 0; i < 4; i++){
00203         t = modulo_three_table[code][i];
00204         if(t == 1)
00205             cbp |= cbp_masks[get_bits1(gb)] << i;
00206         if(t == 2)
00207             cbp |= cbp_masks[2] << i;
00208     }
00209     return cbp;
00210 }
00211 
00215 static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc)
00216 {
00217     if(coef){
00218         if(coef == esc){
00219             coef = get_vlc2(gb, vlc->table, 9, 2);
00220             if(coef > 23){
00221                 coef -= 23;
00222                 coef = 22 + ((1 << coef) | get_bits(gb, coef));
00223             }
00224             coef += esc;
00225         }
00226         if(get_bits1(gb))
00227             coef = -coef;
00228         *dst = coef;
00229     }
00230 }
00231 
00235 static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc)
00236 {
00237     int coeffs[4];
00238 
00239     coeffs[0] = modulo_three_table[code][0];
00240     coeffs[1] = modulo_three_table[code][1];
00241     coeffs[2] = modulo_three_table[code][2];
00242     coeffs[3] = modulo_three_table[code][3];
00243     decode_coeff(dst  , coeffs[0], 3, gb, vlc);
00244     if(is_block2){
00245         decode_coeff(dst+8, coeffs[1], 2, gb, vlc);
00246         decode_coeff(dst+1, coeffs[2], 2, gb, vlc);
00247     }else{
00248         decode_coeff(dst+1, coeffs[1], 2, gb, vlc);
00249         decode_coeff(dst+8, coeffs[2], 2, gb, vlc);
00250     }
00251     decode_coeff(dst+9, coeffs[3], 2, gb, vlc);
00252 }
00253 
00265 static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc)
00266 {
00267     int code, pattern;
00268 
00269     code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2);
00270 
00271     pattern = code & 0x7;
00272 
00273     code >>= 3;
00274     decode_subblock(dst, code, 0, gb, &rvlc->coefficient);
00275 
00276     if(pattern & 4){
00277         code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
00278         decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient);
00279     }
00280     if(pattern & 2){ 
00281         code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
00282         decode_subblock(dst + 8*2, code, 1, gb, &rvlc->coefficient);
00283     }
00284     if(pattern & 1){
00285         code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
00286         decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient);
00287     }
00288 
00289 }
00290 
00295 static inline void rv34_dequant4x4(DCTELEM *block, int Qdc, int Q)
00296 {
00297     int i, j;
00298 
00299     block[0] = (block[0] * Qdc + 8) >> 4;
00300     for(i = 0; i < 4; i++)
00301         for(j = !i; j < 4; j++)
00302             block[j + i*8] = (block[j + i*8] * Q + 8) >> 4;
00303 }
00304 
00309 static inline void rv34_dequant4x4_16x16(DCTELEM *block, int Qdc, int Q)
00310 {
00311     int i;
00312 
00313     for(i = 0; i < 3; i++)
00314          block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Qdc + 8) >> 4;
00315     for(; i < 16; i++)
00316          block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Q + 8) >> 4;
00317 } 
00319 
00320 
00330 int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size)
00331 {
00332     int i;
00333     for(i = 0; i < 5; i++)
00334         if(rv34_mb_max_sizes[i] >= mb_size - 1)
00335             break;
00336     return rv34_mb_bits_sizes[i];
00337 }
00338 
00342 static inline RV34VLC* choose_vlc_set(int quant, int mod, int type)
00343 {
00344     if(mod == 2 && quant < 19) quant += 10;
00345     else if(mod && quant < 26) quant += 5;
00346     return type ? &inter_vlcs[rv34_quant_to_vlc_set[1][av_clip(quant, 0, 30)]]
00347                 : &intra_vlcs[rv34_quant_to_vlc_set[0][av_clip(quant, 0, 30)]];
00348 }
00349 
00353 static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types)
00354 {
00355     MpegEncContext *s = &r->s;
00356     GetBitContext *gb = &s->gb;
00357     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
00358     int i, t;
00359 
00360     if(!r->si.type){
00361         r->is16 = get_bits1(gb);
00362         if(!r->is16 && !r->rv30){
00363             if(!get_bits1(gb))
00364                 av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
00365         }
00366         s->current_picture_ptr->f.mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA;
00367         r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA;
00368     }else{
00369         r->block_type = r->decode_mb_info(r);
00370         if(r->block_type == -1)
00371             return -1;
00372         s->current_picture_ptr->f.mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
00373         r->mb_type[mb_pos] = r->block_type;
00374         if(r->block_type == RV34_MB_SKIP){
00375             if(s->pict_type == AV_PICTURE_TYPE_P)
00376                 r->mb_type[mb_pos] = RV34_MB_P_16x16;
00377             if(s->pict_type == AV_PICTURE_TYPE_B)
00378                 r->mb_type[mb_pos] = RV34_MB_B_DIRECT;
00379         }
00380         r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->f.mb_type[mb_pos]);
00381         rv34_decode_mv(r, r->block_type);
00382         if(r->block_type == RV34_MB_SKIP){
00383             fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0]));
00384             return 0;
00385         }
00386         r->chroma_vlc = 1;
00387         r->luma_vlc   = 0;
00388     }
00389     if(IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])){
00390         if(r->is16){
00391             t = get_bits(gb, 2);
00392             fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
00393             r->luma_vlc   = 2;
00394         }else{
00395             if(r->decode_intra_types(r, gb, intra_types) < 0)
00396                 return -1;
00397             r->luma_vlc   = 1;
00398         }
00399         r->chroma_vlc = 0;
00400         r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
00401     }else{
00402         for(i = 0; i < 16; i++)
00403             intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0;
00404         r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
00405         if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){
00406             r->is16 = 1;
00407             r->chroma_vlc = 1;
00408             r->luma_vlc   = 2;
00409             r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
00410         }
00411     }
00412 
00413     return rv34_decode_cbp(gb, r->cur_vlcs, r->is16);
00414 }
00415  
00417 
00424 static const uint8_t part_sizes_w[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2 };
00425 
00427 static const uint8_t part_sizes_h[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2 };
00428 
00430 static const uint8_t avail_indexes[4] = { 6, 7, 10, 11 };
00431 
00439 static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int dmv_no)
00440 {
00441     MpegEncContext *s = &r->s;
00442     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00443     int A[2] = {0}, B[2], C[2];
00444     int i, j;
00445     int mx, my;
00446     int avail_index = avail_indexes[subblock_no];
00447     int c_off = part_sizes_w[block_type];
00448 
00449     mv_pos += (subblock_no & 1) + (subblock_no >> 1)*s->b8_stride;
00450     if(subblock_no == 3)
00451         c_off = -1;
00452 
00453     if(r->avail_cache[avail_index - 1]){
00454         A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][0];
00455         A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][1];
00456     }
00457     if(r->avail_cache[avail_index - 4]){
00458         B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][0];
00459         B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][1];
00460     }else{
00461         B[0] = A[0];
00462         B[1] = A[1];
00463     }
00464     if(!r->avail_cache[avail_index - 4 + c_off]){
00465         if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1] || r->rv30)){
00466             C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][0];
00467             C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][1];
00468         }else{
00469             C[0] = A[0];
00470             C[1] = A[1];
00471         }
00472     }else{
00473         C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][0];
00474         C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][1];
00475     }
00476     mx = mid_pred(A[0], B[0], C[0]);
00477     my = mid_pred(A[1], B[1], C[1]);
00478     mx += r->dmv[dmv_no][0];
00479     my += r->dmv[dmv_no][1];
00480     for(j = 0; j < part_sizes_h[block_type]; j++){
00481         for(i = 0; i < part_sizes_w[block_type]; i++){
00482             s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
00483             s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
00484         }
00485     }
00486 }
00487 
00488 #define GET_PTS_DIFF(a, b) ((a - b + 8192) & 0x1FFF)
00489 
00493 static int calc_add_mv(RV34DecContext *r, int dir, int val)
00494 {
00495     int mul = dir ? -r->weight2 : r->weight1;
00496 
00497     return (val * mul + 0x2000) >> 14;
00498 }
00499 
00503 static inline void rv34_pred_b_vector(int A[2], int B[2], int C[2],
00504                                       int A_avail, int B_avail, int C_avail,
00505                                       int *mx, int *my)
00506 {
00507     if(A_avail + B_avail + C_avail != 3){
00508         *mx = A[0] + B[0] + C[0];
00509         *my = A[1] + B[1] + C[1];
00510         if(A_avail + B_avail + C_avail == 2){
00511             *mx /= 2;
00512             *my /= 2;
00513         }
00514     }else{
00515         *mx = mid_pred(A[0], B[0], C[0]);
00516         *my = mid_pred(A[1], B[1], C[1]);
00517     }
00518 }
00519 
00523 static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
00524 {
00525     MpegEncContext *s = &r->s;
00526     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
00527     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00528     int A[2], B[2], C[2];
00529     int has_A = 0, has_B = 0, has_C = 0;
00530     int mx, my;
00531     int i, j;
00532     Picture *cur_pic = s->current_picture_ptr;
00533     const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0;
00534     int type = cur_pic->f.mb_type[mb_pos];
00535 
00536     memset(A, 0, sizeof(A));
00537     memset(B, 0, sizeof(B));
00538     memset(C, 0, sizeof(C));
00539     if((r->avail_cache[6-1] & type) & mask){
00540         A[0] = cur_pic->f.motion_val[dir][mv_pos - 1][0];
00541         A[1] = cur_pic->f.motion_val[dir][mv_pos - 1][1];
00542         has_A = 1;
00543     }
00544     if((r->avail_cache[6-4] & type) & mask){
00545         B[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][0];
00546         B[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][1];
00547         has_B = 1;
00548     }
00549     if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){
00550         C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][0];
00551         C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][1];
00552         has_C = 1;
00553     }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){
00554         C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][0];
00555         C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][1];
00556         has_C = 1;
00557     }
00558 
00559     rv34_pred_b_vector(A, B, C, has_A, has_B, has_C, &mx, &my);
00560 
00561     mx += r->dmv[dir][0];
00562     my += r->dmv[dir][1];
00563 
00564     for(j = 0; j < 2; j++){
00565         for(i = 0; i < 2; i++){
00566             cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
00567             cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
00568         }
00569     }
00570     if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){
00571         ZERO8x2(cur_pic->f.motion_val[!dir][mv_pos], s->b8_stride);
00572     }
00573 }
00574 
00578 static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
00579 {
00580     MpegEncContext *s = &r->s;
00581     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00582     int A[2] = {0}, B[2], C[2];
00583     int i, j, k;
00584     int mx, my;
00585     int avail_index = avail_indexes[0];
00586 
00587     if(r->avail_cache[avail_index - 1]){
00588         A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][0];
00589         A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][1];
00590     }
00591     if(r->avail_cache[avail_index - 4]){
00592         B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][0];
00593         B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][1];
00594     }else{
00595         B[0] = A[0];
00596         B[1] = A[1];
00597     }
00598     if(!r->avail_cache[avail_index - 4 + 2]){
00599         if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1])){
00600             C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][0];
00601             C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][1];
00602         }else{
00603             C[0] = A[0];
00604             C[1] = A[1];
00605         }
00606     }else{
00607         C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][0];
00608         C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][1];
00609     }
00610     mx = mid_pred(A[0], B[0], C[0]);
00611     my = mid_pred(A[1], B[1], C[1]);
00612     mx += r->dmv[0][0];
00613     my += r->dmv[0][1];
00614     for(j = 0; j < 2; j++){
00615         for(i = 0; i < 2; i++){
00616             for(k = 0; k < 2; k++){
00617                 s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
00618                 s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
00619             }
00620         }
00621     }
00622 }
00623 
00624 static const int chroma_coeffs[3] = { 0, 3, 5 };
00625 
00641 static inline void rv34_mc(RV34DecContext *r, const int block_type,
00642                           const int xoff, const int yoff, int mv_off,
00643                           const int width, const int height, int dir,
00644                           const int thirdpel, int weighted,
00645                           qpel_mc_func (*qpel_mc)[16],
00646                           h264_chroma_mc_func (*chroma_mc))
00647 {
00648     MpegEncContext *s = &r->s;
00649     uint8_t *Y, *U, *V, *srcY, *srcU, *srcV;
00650     int dxy, mx, my, umx, umy, lx, ly, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
00651     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + mv_off;
00652     int is16x16 = 1;
00653 
00654     if(thirdpel){
00655         int chroma_mx, chroma_my;
00656         mx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
00657         my = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
00658         lx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
00659         ly = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
00660         chroma_mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2;
00661         chroma_my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2;
00662         umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24);
00663         umy = (chroma_my + (3 << 24)) / 3 - (1 << 24);
00664         uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3];
00665         uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3];
00666     }else{
00667         int cx, cy;
00668         mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] >> 2;
00669         my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] >> 2;
00670         lx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] & 3;
00671         ly = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] & 3;
00672         cx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2;
00673         cy = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2;
00674         umx = cx >> 2;
00675         umy = cy >> 2;
00676         uvmx = (cx & 3) << 1;
00677         uvmy = (cy & 3) << 1;
00678         
00679         if(uvmx == 6 && uvmy == 6)
00680             uvmx = uvmy = 4;
00681     }
00682     dxy = ly*4 + lx;
00683     srcY = dir ? s->next_picture_ptr->f.data[0] : s->last_picture_ptr->f.data[0];
00684     srcU = dir ? s->next_picture_ptr->f.data[1] : s->last_picture_ptr->f.data[1];
00685     srcV = dir ? s->next_picture_ptr->f.data[2] : s->last_picture_ptr->f.data[2];
00686     src_x = s->mb_x * 16 + xoff + mx;
00687     src_y = s->mb_y * 16 + yoff + my;
00688     uvsrc_x = s->mb_x * 8 + (xoff >> 1) + umx;
00689     uvsrc_y = s->mb_y * 8 + (yoff >> 1) + umy;
00690     srcY += src_y * s->linesize + src_x;
00691     srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
00692     srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
00693     if(s->h_edge_pos - (width << 3) < 6 || s->v_edge_pos - (height << 3) < 6 ||
00694        (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4 ||
00695        (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4) {
00696         uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize;
00697 
00698         srcY -= 2 + 2*s->linesize;
00699         s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6,
00700                             src_x - 2, src_y - 2, s->h_edge_pos, s->v_edge_pos);
00701         srcY = s->edge_emu_buffer + 2 + 2*s->linesize;
00702         s->dsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1,
00703                             uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
00704         s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1,
00705                             uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
00706         srcU = uvbuf;
00707         srcV = uvbuf + 16;
00708     }
00709     if(!weighted){
00710         Y = s->dest[0] + xoff      + yoff     *s->linesize;
00711         U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
00712         V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
00713     }else{
00714         Y = r->tmp_b_block_y [dir]     +  xoff     +  yoff    *s->linesize;
00715         U = r->tmp_b_block_uv[dir*2]   + (xoff>>1) + (yoff>>1)*s->uvlinesize;
00716         V = r->tmp_b_block_uv[dir*2+1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
00717     }
00718 
00719     if(block_type == RV34_MB_P_16x8){
00720         qpel_mc[1][dxy](Y, srcY, s->linesize);
00721         Y    += 8;
00722         srcY += 8;
00723     }else if(block_type == RV34_MB_P_8x16){
00724         qpel_mc[1][dxy](Y, srcY, s->linesize);
00725         Y    += 8 * s->linesize;
00726         srcY += 8 * s->linesize;
00727     }
00728     is16x16 = (block_type != RV34_MB_P_8x8) && (block_type != RV34_MB_P_16x8) && (block_type != RV34_MB_P_8x16);
00729     qpel_mc[!is16x16][dxy](Y, srcY, s->linesize);
00730     chroma_mc[2-width]   (U, srcU, s->uvlinesize, height*4, uvmx, uvmy);
00731     chroma_mc[2-width]   (V, srcV, s->uvlinesize, height*4, uvmx, uvmy);
00732 }
00733 
00734 static void rv34_mc_1mv(RV34DecContext *r, const int block_type,
00735                         const int xoff, const int yoff, int mv_off,
00736                         const int width, const int height, int dir)
00737 {
00738     rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30, 0,
00739             r->rdsp.put_pixels_tab,
00740             r->rdsp.put_chroma_pixels_tab);
00741 }
00742 
00743 static void rv4_weight(RV34DecContext *r)
00744 {
00745     r->rdsp.rv40_weight_pixels_tab[0](r->s.dest[0],
00746                                       r->tmp_b_block_y[0],
00747                                       r->tmp_b_block_y[1],
00748                                       r->weight1,
00749                                       r->weight2,
00750                                       r->s.linesize);
00751     r->rdsp.rv40_weight_pixels_tab[1](r->s.dest[1],
00752                                       r->tmp_b_block_uv[0],
00753                                       r->tmp_b_block_uv[2],
00754                                       r->weight1,
00755                                       r->weight2,
00756                                       r->s.uvlinesize);
00757     r->rdsp.rv40_weight_pixels_tab[1](r->s.dest[2],
00758                                       r->tmp_b_block_uv[1],
00759                                       r->tmp_b_block_uv[3],
00760                                       r->weight1,
00761                                       r->weight2,
00762                                       r->s.uvlinesize);
00763 }
00764 
00765 static void rv34_mc_2mv(RV34DecContext *r, const int block_type)
00766 {
00767     int weighted = !r->rv30 && block_type != RV34_MB_B_BIDIR && r->weight1 != 8192;
00768 
00769     rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30, weighted,
00770             r->rdsp.put_pixels_tab,
00771             r->rdsp.put_chroma_pixels_tab);
00772     if(!weighted){
00773         rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 0,
00774                 r->rdsp.avg_pixels_tab,
00775                 r->rdsp.avg_chroma_pixels_tab);
00776     }else{
00777         rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 1,
00778                 r->rdsp.put_pixels_tab,
00779                 r->rdsp.put_chroma_pixels_tab);
00780         rv4_weight(r);
00781     }
00782 }
00783 
00784 static void rv34_mc_2mv_skip(RV34DecContext *r)
00785 {
00786     int i, j;
00787     int weighted = !r->rv30 && r->weight1 != 8192;
00788 
00789     for(j = 0; j < 2; j++)
00790         for(i = 0; i < 2; i++){
00791              rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30,
00792                      weighted,
00793                      r->rdsp.put_pixels_tab,
00794                      r->rdsp.put_chroma_pixels_tab);
00795              rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30,
00796                      weighted,
00797                      weighted ? r->rdsp.put_pixels_tab : r->rdsp.avg_pixels_tab,
00798                      weighted ? r->rdsp.put_chroma_pixels_tab : r->rdsp.avg_chroma_pixels_tab);
00799         }
00800     if(weighted)
00801         rv4_weight(r);
00802 }
00803 
00805 static const int num_mvs[RV34_MB_TYPES] = { 0, 0, 1, 4, 1, 1, 0, 0, 2, 2, 2, 1 };
00806 
00811 static int rv34_decode_mv(RV34DecContext *r, int block_type)
00812 {
00813     MpegEncContext *s = &r->s;
00814     GetBitContext *gb = &s->gb;
00815     int i, j, k, l;
00816     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00817     int next_bt;
00818 
00819     memset(r->dmv, 0, sizeof(r->dmv));
00820     for(i = 0; i < num_mvs[block_type]; i++){
00821         r->dmv[i][0] = svq3_get_se_golomb(gb);
00822         r->dmv[i][1] = svq3_get_se_golomb(gb);
00823     }
00824     switch(block_type){
00825     case RV34_MB_TYPE_INTRA:
00826     case RV34_MB_TYPE_INTRA16x16:
00827         ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00828         return 0;
00829     case RV34_MB_SKIP:
00830         if(s->pict_type == AV_PICTURE_TYPE_P){
00831             ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00832             rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
00833             break;
00834         }
00835     case RV34_MB_B_DIRECT:
00836         
00837         next_bt = s->next_picture_ptr->f.mb_type[s->mb_x + s->mb_y * s->mb_stride];
00838         if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){
00839             ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00840             ZERO8x2(s->current_picture_ptr->f.motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00841         }else
00842             for(j = 0; j < 2; j++)
00843                 for(i = 0; i < 2; i++)
00844                     for(k = 0; k < 2; k++)
00845                         for(l = 0; l < 2; l++)
00846                             s->current_picture_ptr->f.motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][k]);
00847         if(!(IS_16X8(next_bt) || IS_8X16(next_bt) || IS_8X8(next_bt))) 
00848             rv34_mc_2mv(r, block_type);
00849         else
00850             rv34_mc_2mv_skip(r);
00851         ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00852         break;
00853     case RV34_MB_P_16x16:
00854     case RV34_MB_P_MIX16x16:
00855         rv34_pred_mv(r, block_type, 0, 0);
00856         rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
00857         break;
00858     case RV34_MB_B_FORWARD:
00859     case RV34_MB_B_BACKWARD:
00860         r->dmv[1][0] = r->dmv[0][0];
00861         r->dmv[1][1] = r->dmv[0][1];
00862         if(r->rv30)
00863             rv34_pred_mv_rv3(r, block_type, block_type == RV34_MB_B_BACKWARD);
00864         else
00865             rv34_pred_mv_b  (r, block_type, block_type == RV34_MB_B_BACKWARD);
00866         rv34_mc_1mv     (r, block_type, 0, 0, 0, 2, 2, block_type == RV34_MB_B_BACKWARD);
00867         break;
00868     case RV34_MB_P_16x8:
00869     case RV34_MB_P_8x16:
00870         rv34_pred_mv(r, block_type, 0, 0);
00871         rv34_pred_mv(r, block_type, 1 + (block_type == RV34_MB_P_16x8), 1);
00872         if(block_type == RV34_MB_P_16x8){
00873             rv34_mc_1mv(r, block_type, 0, 0, 0,            2, 1, 0);
00874             rv34_mc_1mv(r, block_type, 0, 8, s->b8_stride, 2, 1, 0);
00875         }
00876         if(block_type == RV34_MB_P_8x16){
00877             rv34_mc_1mv(r, block_type, 0, 0, 0, 1, 2, 0);
00878             rv34_mc_1mv(r, block_type, 8, 0, 1, 1, 2, 0);
00879         }
00880         break;
00881     case RV34_MB_B_BIDIR:
00882         rv34_pred_mv_b  (r, block_type, 0);
00883         rv34_pred_mv_b  (r, block_type, 1);
00884         rv34_mc_2mv     (r, block_type);
00885         break;
00886     case RV34_MB_P_8x8:
00887         for(i=0;i< 4;i++){
00888             rv34_pred_mv(r, block_type, i, i);
00889             rv34_mc_1mv (r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1, 0);
00890         }
00891         break;
00892     }
00893 
00894     return 0;
00895 } 
00897 
00903 static const int ittrans[9] = {
00904  DC_PRED, VERT_PRED, HOR_PRED, DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_LEFT_PRED,
00905  VERT_RIGHT_PRED, VERT_LEFT_PRED, HOR_UP_PRED, HOR_DOWN_PRED,
00906 };
00907 
00909 static const int ittrans16[4] = {
00910  DC_PRED8x8, VERT_PRED8x8, HOR_PRED8x8, PLANE_PRED8x8,
00911 };
00912 
00916 static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int itype, int up, int left, int down, int right)
00917 {
00918     uint8_t *prev = dst - stride + 4;
00919     uint32_t topleft;
00920 
00921     if(!up && !left)
00922         itype = DC_128_PRED;
00923     else if(!up){
00924         if(itype == VERT_PRED) itype = HOR_PRED;
00925         if(itype == DC_PRED)   itype = LEFT_DC_PRED;
00926     }else if(!left){
00927         if(itype == HOR_PRED)  itype = VERT_PRED;
00928         if(itype == DC_PRED)   itype = TOP_DC_PRED;
00929         if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
00930     }
00931     if(!down){
00932         if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
00933         if(itype == HOR_UP_PRED) itype = HOR_UP_PRED_RV40_NODOWN;
00934         if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN;
00935     }
00936     if(!right && up){
00937         topleft = dst[-stride + 3] * 0x01010101u;
00938         prev = (uint8_t*)&topleft;
00939     }
00940     r->h.pred4x4[itype](dst, prev, stride);
00941 }
00942 
00944 static void rv34_add_4x4_block(uint8_t *dst, int stride, DCTELEM block[64], int off)
00945 {
00946     int x, y;
00947     for(y = 0; y < 4; y++)
00948         for(x = 0; x < 4; x++)
00949             dst[x + y*stride] = av_clip_uint8(dst[x + y*stride] + block[off + x+y*8]);
00950 }
00951 
00952 static inline int adjust_pred16(int itype, int up, int left)
00953 {
00954     if(!up && !left)
00955         itype = DC_128_PRED8x8;
00956     else if(!up){
00957         if(itype == PLANE_PRED8x8)itype = HOR_PRED8x8;
00958         if(itype == VERT_PRED8x8) itype = HOR_PRED8x8;
00959         if(itype == DC_PRED8x8)   itype = LEFT_DC_PRED8x8;
00960     }else if(!left){
00961         if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8;
00962         if(itype == HOR_PRED8x8)  itype = VERT_PRED8x8;
00963         if(itype == DC_PRED8x8)   itype = TOP_DC_PRED8x8;
00964     }
00965     return itype;
00966 }
00967 
00968 static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int cbp, int is16)
00969 {
00970     MpegEncContext *s = &r->s;
00971     DSPContext *dsp = &s->dsp;
00972     int i, j;
00973     uint8_t *Y, *U, *V;
00974     int itype;
00975     int avail[6*8] = {0};
00976     int idx;
00977 
00978     
00979     if(r->avail_cache[1])
00980         avail[0] = 1;
00981     if(r->avail_cache[2])
00982         avail[1] = avail[2] = 1;
00983     if(r->avail_cache[3])
00984         avail[3] = avail[4] = 1;
00985     if(r->avail_cache[4])
00986         avail[5] = 1;
00987     if(r->avail_cache[5])
00988         avail[8] = avail[16] = 1;
00989     if(r->avail_cache[9])
00990         avail[24] = avail[32] = 1;
00991 
00992     Y = s->dest[0];
00993     U = s->dest[1];
00994     V = s->dest[2];
00995     if(!is16){
00996         for(j = 0; j < 4; j++){
00997             idx = 9 + j*8;
00998             for(i = 0; i < 4; i++, cbp >>= 1, Y += 4, idx++){
00999                 rv34_pred_4x4_block(r, Y, s->linesize, ittrans[intra_types[i]], avail[idx-8], avail[idx-1], avail[idx+7], avail[idx-7]);
01000                 avail[idx] = 1;
01001                 if(cbp & 1)
01002                     rv34_add_4x4_block(Y, s->linesize, s->block[(i>>1)+(j&2)], (i&1)*4+(j&1)*32);
01003             }
01004             Y += s->linesize * 4 - 4*4;
01005             intra_types += r->intra_types_stride;
01006         }
01007         intra_types -= r->intra_types_stride * 4;
01008         fill_rectangle(r->avail_cache + 6, 2, 2, 4, 0, 4);
01009         for(j = 0; j < 2; j++){
01010             idx = 6 + j*4;
01011             for(i = 0; i < 2; i++, cbp >>= 1, idx++){
01012                 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]);
01013                 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]);
01014                 r->avail_cache[idx] = 1;
01015                 if(cbp & 0x01)
01016                     rv34_add_4x4_block(U + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[4], i*4+j*32);
01017                 if(cbp & 0x10)
01018                     rv34_add_4x4_block(V + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[5], i*4+j*32);
01019             }
01020         }
01021     }else{
01022         itype = ittrans16[intra_types[0]];
01023         itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
01024         r->h.pred16x16[itype](Y, s->linesize);
01025         dsp->add_pixels_clamped(s->block[0], Y,     s->linesize);
01026         dsp->add_pixels_clamped(s->block[1], Y + 8, s->linesize);
01027         Y += s->linesize * 8;
01028         dsp->add_pixels_clamped(s->block[2], Y,     s->linesize);
01029         dsp->add_pixels_clamped(s->block[3], Y + 8, s->linesize);
01030 
01031         itype = ittrans16[intra_types[0]];
01032         if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
01033         itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
01034         r->h.pred8x8[itype](U, s->uvlinesize);
01035         dsp->add_pixels_clamped(s->block[4], U, s->uvlinesize);
01036         r->h.pred8x8[itype](V, s->uvlinesize);
01037         dsp->add_pixels_clamped(s->block[5], V, s->uvlinesize);
01038     }
01039 }
01040 
01045 #define LUMA_CBP_BLOCK_MASK 0x33
01046 
01047 #define U_CBP_MASK 0x0F0000
01048 #define V_CBP_MASK 0xF00000
01049  
01051 
01052 
01053 static void rv34_apply_differences(RV34DecContext *r, int cbp)
01054 {
01055     static const int shifts[4] = { 0, 2, 8, 10 };
01056     MpegEncContext *s = &r->s;
01057     int i;
01058 
01059     for(i = 0; i < 4; i++)
01060         if((cbp & (LUMA_CBP_BLOCK_MASK << shifts[i])) || r->block_type == RV34_MB_P_MIX16x16)
01061             s->dsp.add_pixels_clamped(s->block[i], s->dest[0] + (i & 1)*8 + (i&2)*4*s->linesize, s->linesize);
01062     if(cbp & U_CBP_MASK)
01063         s->dsp.add_pixels_clamped(s->block[4], s->dest[1], s->uvlinesize);
01064     if(cbp & V_CBP_MASK)
01065         s->dsp.add_pixels_clamped(s->block[5], s->dest[2], s->uvlinesize);
01066 }
01067 
01068 static int is_mv_diff_gt_3(int16_t (*motion_val)[2], int step)
01069 {
01070     int d;
01071     d = motion_val[0][0] - motion_val[-step][0];
01072     if(d < -3 || d > 3)
01073         return 1;
01074     d = motion_val[0][1] - motion_val[-step][1];
01075     if(d < -3 || d > 3)
01076         return 1;
01077     return 0;
01078 }
01079 
01080 static int rv34_set_deblock_coef(RV34DecContext *r)
01081 {
01082     MpegEncContext *s = &r->s;
01083     int hmvmask = 0, vmvmask = 0, i, j;
01084     int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
01085     int16_t (*motion_val)[2] = &s->current_picture_ptr->f.motion_val[0][midx];
01086     for(j = 0; j < 16; j += 8){
01087         for(i = 0; i < 2; i++){
01088             if(is_mv_diff_gt_3(motion_val + i, 1))
01089                 vmvmask |= 0x11 << (j + i*2);
01090             if((j || s->mb_y) && is_mv_diff_gt_3(motion_val + i, s->b8_stride))
01091                 hmvmask |= 0x03 << (j + i*2);
01092         }
01093         motion_val += s->b8_stride;
01094     }
01095     if(s->first_slice_line)
01096         hmvmask &= ~0x000F;
01097     if(!s->mb_x)
01098         vmvmask &= ~0x1111;
01099     if(r->rv30){ 
01100         vmvmask |= (vmvmask & 0x4444) >> 1;
01101         hmvmask |= (hmvmask & 0x0F00) >> 4;
01102         if(s->mb_x)
01103             r->deblock_coefs[s->mb_x - 1 + s->mb_y*s->mb_stride] |= (vmvmask & 0x1111) << 3;
01104         if(!s->first_slice_line)
01105             r->deblock_coefs[s->mb_x + (s->mb_y - 1)*s->mb_stride] |= (hmvmask & 0xF) << 12;
01106     }
01107     return hmvmask | vmvmask;
01108 }
01109 
01110 static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
01111 {
01112     MpegEncContext *s = &r->s;
01113     GetBitContext *gb = &s->gb;
01114     int cbp, cbp2;
01115     int i, blknum, blkoff;
01116     LOCAL_ALIGNED_16(DCTELEM, block16, [64]);
01117     int luma_dc_quant;
01118     int dist;
01119     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
01120 
01121     
01122     memset(r->avail_cache, 0, sizeof(r->avail_cache));
01123     fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4);
01124     dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
01125     if(s->mb_x && dist)
01126         r->avail_cache[5] =
01127         r->avail_cache[9] = s->current_picture_ptr->f.mb_type[mb_pos - 1];
01128     if(dist >= s->mb_width)
01129         r->avail_cache[2] =
01130         r->avail_cache[3] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride];
01131     if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
01132         r->avail_cache[4] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride + 1];
01133     if(s->mb_x && dist > s->mb_width)
01134         r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1];
01135 
01136     s->qscale = r->si.quant;
01137     cbp = cbp2 = rv34_decode_mb_header(r, intra_types);
01138     r->cbp_luma  [mb_pos] = cbp;
01139     r->cbp_chroma[mb_pos] = cbp >> 16;
01140     if(s->pict_type == AV_PICTURE_TYPE_I)
01141         r->deblock_coefs[mb_pos] = 0xFFFF;
01142     else
01143         r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos];
01144     s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale;
01145 
01146     if(cbp == -1)
01147         return -1;
01148 
01149     luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16 ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale];
01150     if(r->is16){
01151         memset(block16, 0, 64 * sizeof(*block16));
01152         rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0);
01153         rv34_dequant4x4_16x16(block16, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
01154         r->rdsp.rv34_inv_transform_tab[1](block16);
01155     }
01156 
01157     for(i = 0; i < 16; i++, cbp >>= 1){
01158         if(!r->is16 && !(cbp & 1)) continue;
01159         blknum = ((i & 2) >> 1) + ((i & 8) >> 2);
01160         blkoff = ((i & 1) << 2) + ((i & 4) << 3);
01161         if(cbp & 1)
01162             rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0);
01163         rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[s->qscale],rv34_qscale_tab[s->qscale]);
01164         if(r->is16) 
01165             s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)];
01166         r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
01167     }
01168     if(r->block_type == RV34_MB_P_MIX16x16)
01169         r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
01170     for(; i < 24; i++, cbp >>= 1){
01171         if(!(cbp & 1)) continue;
01172         blknum = ((i & 4) >> 2) + 4;
01173         blkoff = ((i & 1) << 2) + ((i & 2) << 4);
01174         rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1);
01175         rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]);
01176         r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
01177     }
01178     if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos]))
01179         rv34_output_macroblock(r, intra_types, cbp2, r->is16);
01180     else
01181         rv34_apply_differences(r, cbp2);
01182 
01183     return 0;
01184 }
01185 
01186 static int check_slice_end(RV34DecContext *r, MpegEncContext *s)
01187 {
01188     int bits;
01189     if(s->mb_y >= s->mb_height)
01190         return 1;
01191     if(!s->mb_num_left)
01192         return 1;
01193     if(r->s.mb_skip_run > 1)
01194         return 0;
01195     bits = r->bits - get_bits_count(&s->gb);
01196     if(bits < 0 || (bits < 8 && !show_bits(&s->gb, bits)))
01197         return 1;
01198     return 0;
01199 }
01200 
01201 static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int buf_size)
01202 {
01203     MpegEncContext *s = &r->s;
01204     GetBitContext *gb = &s->gb;
01205     int mb_pos;
01206     int res;
01207 
01208     init_get_bits(&r->s.gb, buf, buf_size*8);
01209     res = r->parse_slice_header(r, gb, &r->si);
01210     if(res < 0){
01211         av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n");
01212         return -1;
01213     }
01214 
01215     if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
01216         if(s->width != r->si.width || s->height != r->si.height){
01217             av_log(s->avctx, AV_LOG_DEBUG, "Changing dimensions to %dx%d\n", r->si.width,r->si.height);
01218             MPV_common_end(s);
01219             s->width  = r->si.width;
01220             s->height = r->si.height;
01221             avcodec_set_dimensions(s->avctx, s->width, s->height);
01222             if(MPV_common_init(s) < 0)
01223                 return -1;
01224             r->intra_types_stride = s->mb_width*4 + 4;
01225             r->intra_types_hist = av_realloc(r->intra_types_hist, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
01226             r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;
01227             r->mb_type = av_realloc(r->mb_type, r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type));
01228             r->cbp_luma   = av_realloc(r->cbp_luma,   r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma));
01229             r->cbp_chroma = av_realloc(r->cbp_chroma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma));
01230             r->deblock_coefs = av_realloc(r->deblock_coefs, r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs));
01231             av_freep(&r->tmp_b_block_base);
01232         }
01233         s->pict_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
01234         if(MPV_frame_start(s, s->avctx) < 0)
01235             return -1;
01236         ff_er_frame_start(s);
01237         if (!r->tmp_b_block_base) {
01238             int i;
01239 
01240             r->tmp_b_block_base = av_malloc(s->linesize * 48);
01241             for (i = 0; i < 2; i++)
01242                 r->tmp_b_block_y[i] = r->tmp_b_block_base + i * 16 * s->linesize;
01243             for (i = 0; i < 4; i++)
01244                 r->tmp_b_block_uv[i] = r->tmp_b_block_base + 32 * s->linesize
01245                                        + (i >> 1) * 8 * s->uvlinesize + (i & 1) * 16;
01246         }
01247         r->cur_pts = r->si.pts;
01248         if(s->pict_type != AV_PICTURE_TYPE_B){
01249             r->last_pts = r->next_pts;
01250             r->next_pts = r->cur_pts;
01251         }else{
01252             int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
01253             int dist0   = GET_PTS_DIFF(r->cur_pts,  r->last_pts);
01254             int dist1   = GET_PTS_DIFF(r->next_pts, r->cur_pts);
01255 
01256             if(!refdist){
01257                 r->weight1 = r->weight2 = 8192;
01258             }else{
01259                 r->weight1 = (dist0 << 14) / refdist;
01260                 r->weight2 = (dist1 << 14) / refdist;
01261             }
01262         }
01263         s->mb_x = s->mb_y = 0;
01264     } else {
01265         int slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
01266 
01267         if (slice_type != s->pict_type) {
01268             av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
01269             return AVERROR_INVALIDDATA;
01270         }
01271         if (s->width != r->si.width || s->height != r->si.height) {
01272             av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n");
01273             return AVERROR_INVALIDDATA;
01274         }
01275     }
01276 
01277     r->si.end = end;
01278     s->qscale = r->si.quant;
01279     r->bits = buf_size*8;
01280     s->mb_num_left = r->si.end - r->si.start;
01281     r->s.mb_skip_run = 0;
01282 
01283     mb_pos = s->mb_x + s->mb_y * s->mb_width;
01284     if(r->si.start != mb_pos){
01285         av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->si.start, mb_pos);
01286         s->mb_x = r->si.start % s->mb_width;
01287         s->mb_y = r->si.start / s->mb_width;
01288     }
01289     memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
01290     s->first_slice_line = 1;
01291     s->resync_mb_x = s->mb_x;
01292     s->resync_mb_y = s->mb_y;
01293 
01294     ff_init_block_index(s);
01295     while(!check_slice_end(r, s)) {
01296         ff_update_block_index(s);
01297         s->dsp.clear_blocks(s->block[0]);
01298 
01299         if(rv34_decode_macroblock(r, r->intra_types + s->mb_x * 4 + 4) < 0){
01300             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);
01301             return -1;
01302         }
01303         if (++s->mb_x == s->mb_width) {
01304             s->mb_x = 0;
01305             s->mb_y++;
01306             ff_init_block_index(s);
01307 
01308             memmove(r->intra_types_hist, r->intra_types, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));
01309             memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));
01310 
01311             if(r->loop_filter && s->mb_y >= 2)
01312                 r->loop_filter(r, s->mb_y - 2);
01313         }
01314         if(s->mb_x == s->resync_mb_x)
01315             s->first_slice_line=0;
01316         s->mb_num_left--;
01317     }
01318     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);
01319 
01320     return s->mb_y == s->mb_height;
01321 }
01322  
01324 
01328 av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
01329 {
01330     RV34DecContext *r = avctx->priv_data;
01331     MpegEncContext *s = &r->s;
01332 
01333     MPV_decode_defaults(s);
01334     s->avctx      = avctx;
01335     s->out_format = FMT_H263;
01336     s->codec_id   = avctx->codec_id;
01337 
01338     s->width  = avctx->width;
01339     s->height = avctx->height;
01340 
01341     r->s.avctx = avctx;
01342     avctx->flags |= CODEC_FLAG_EMU_EDGE;
01343     r->s.flags |= CODEC_FLAG_EMU_EDGE;
01344     avctx->pix_fmt = PIX_FMT_YUV420P;
01345     avctx->has_b_frames = 1;
01346     s->low_delay = 0;
01347 
01348     if (MPV_common_init(s) < 0)
01349         return -1;
01350 
01351     ff_h264_pred_init(&r->h, CODEC_ID_RV40, 8, 1);
01352 
01353 #if CONFIG_RV30_DECODER
01354     if (avctx->codec_id == CODEC_ID_RV30)
01355         ff_rv30dsp_init(&r->rdsp, &r->s.dsp);
01356 #endif
01357 #if CONFIG_RV40_DECODER
01358     if (avctx->codec_id == CODEC_ID_RV40)
01359         ff_rv40dsp_init(&r->rdsp, &r->s.dsp);
01360 #endif
01361 
01362     r->intra_types_stride = 4*s->mb_stride + 4;
01363     r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
01364     r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;
01365 
01366     r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type));
01367 
01368     r->cbp_luma   = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma));
01369     r->cbp_chroma = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma));
01370     r->deblock_coefs = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs));
01371 
01372     if(!intra_vlcs[0].cbppattern[0].bits)
01373         rv34_init_tables();
01374 
01375     return 0;
01376 }
01377 
01378 static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n)
01379 {
01380     if(avctx->slice_count) return avctx->slice_offset[n];
01381     else                   return AV_RL32(buf + n*8 - 4) == 1 ? AV_RL32(buf + n*8) :  AV_RB32(buf + n*8);
01382 }
01383 
01384 int ff_rv34_decode_frame(AVCodecContext *avctx,
01385                             void *data, int *data_size,
01386                             AVPacket *avpkt)
01387 {
01388     const uint8_t *buf = avpkt->data;
01389     int buf_size = avpkt->size;
01390     RV34DecContext *r = avctx->priv_data;
01391     MpegEncContext *s = &r->s;
01392     AVFrame *pict = data;
01393     SliceInfo si;
01394     int i;
01395     int slice_count;
01396     const uint8_t *slices_hdr = NULL;
01397     int last = 0;
01398 
01399     
01400     if (buf_size == 0) {
01401         
01402         if (s->low_delay==0 && s->next_picture_ptr) {
01403             *pict = *(AVFrame*)s->next_picture_ptr;
01404             s->next_picture_ptr = NULL;
01405 
01406             *data_size = sizeof(AVFrame);
01407         }
01408         return 0;
01409     }
01410 
01411     if(!avctx->slice_count){
01412         slice_count = (*buf++) + 1;
01413         slices_hdr = buf + 4;
01414         buf += 8 * slice_count;
01415         buf_size -= 1 + 8 * slice_count;
01416     }else
01417         slice_count = avctx->slice_count;
01418 
01419     
01420     if(get_slice_offset(avctx, slices_hdr, 0) < 0 ||
01421        get_slice_offset(avctx, slices_hdr, 0) > buf_size){
01422         av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
01423         return -1;
01424     }
01425     init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), (buf_size-get_slice_offset(avctx, slices_hdr, 0))*8);
01426     if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){
01427         av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");
01428         return -1;
01429     }
01430     if ((!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) && si.type == AV_PICTURE_TYPE_B)
01431         return -1;
01432     if(   (avctx->skip_frame >= AVDISCARD_NONREF && si.type==AV_PICTURE_TYPE_B)
01433        || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=AV_PICTURE_TYPE_I)
01434        ||  avctx->skip_frame >= AVDISCARD_ALL)
01435         return avpkt->size;
01436 
01437     for(i = 0; i < slice_count; i++){
01438         int offset = get_slice_offset(avctx, slices_hdr, i);
01439         int size;
01440         if(i+1 == slice_count)
01441             size = buf_size - offset;
01442         else
01443             size = get_slice_offset(avctx, slices_hdr, i+1) - offset;
01444 
01445         if(offset < 0 || offset > buf_size){
01446             av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
01447             break;
01448         }
01449 
01450         r->si.end = s->mb_width * s->mb_height;
01451         if(i+1 < slice_count){
01452             if (get_slice_offset(avctx, slices_hdr, i+1) < 0 ||
01453                 get_slice_offset(avctx, slices_hdr, i+1) > buf_size) {
01454                 av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
01455                 break;
01456             }
01457             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);
01458             if(r->parse_slice_header(r, &r->s.gb, &si) < 0){
01459                 if(i+2 < slice_count)
01460                     size = get_slice_offset(avctx, slices_hdr, i+2) - offset;
01461                 else
01462                     size = buf_size - offset;
01463             }else
01464                 r->si.end = si.start;
01465         }
01466         if (size < 0 || size > buf_size - offset) {
01467             av_log(avctx, AV_LOG_ERROR, "Slice size is invalid\n");
01468             break;
01469         }
01470         last = rv34_decode_slice(r, r->si.end, buf + offset, size);
01471         s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;
01472         if(last)
01473             break;
01474     }
01475 
01476     if(last && s->current_picture_ptr){
01477         if(r->loop_filter)
01478             r->loop_filter(r, s->mb_height - 1);
01479         ff_er_frame_end(s);
01480         MPV_frame_end(s);
01481         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
01482             *pict = *(AVFrame*)s->current_picture_ptr;
01483         } else if (s->last_picture_ptr != NULL) {
01484             *pict = *(AVFrame*)s->last_picture_ptr;
01485         }
01486 
01487         if(s->last_picture_ptr || s->low_delay){
01488             *data_size = sizeof(AVFrame);
01489             ff_print_debug_info(s, pict);
01490         }
01491         s->current_picture_ptr = NULL; 
01492     }
01493     return avpkt->size;
01494 }
01495 
01496 av_cold int ff_rv34_decode_end(AVCodecContext *avctx)
01497 {
01498     RV34DecContext *r = avctx->priv_data;
01499 
01500     MPV_common_end(&r->s);
01501 
01502     av_freep(&r->intra_types_hist);
01503     r->intra_types = NULL;
01504     av_freep(&r->tmp_b_block_base);
01505     av_freep(&r->mb_type);
01506     av_freep(&r->cbp_luma);
01507     av_freep(&r->cbp_chroma);
01508     av_freep(&r->deblock_coefs);
01509 
01510     return 0;
01511 }