• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • 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 Libav.
00006  *
00007  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #include "libavutil/internal.h"
00028 
00029 #include "avcodec.h"
00030 #include "dsputil.h"
00031 #include "mpegvideo.h"
00032 #include "golomb.h"
00033 #include "internal.h"
00034 #include "mathops.h"
00035 #include "rectangle.h"
00036 #include "thread.h"
00037 
00038 #include "rv34vlc.h"
00039 #include "rv34data.h"
00040 #include "rv34.h"
00041 
00042 //#define DEBUG
00043 
00044 static inline void ZERO8x2(void* dst, int stride)
00045 {
00046     fill_rectangle(dst,                 1, 2, stride, 0, 4);
00047     fill_rectangle(((uint8_t*)(dst))+4, 1, 2, stride, 0, 4);
00048 }
00049 
00051 static const int rv34_mb_type_to_lavc[12] = {
00052     MB_TYPE_INTRA,
00053     MB_TYPE_INTRA16x16              | MB_TYPE_SEPARATE_DC,
00054     MB_TYPE_16x16   | MB_TYPE_L0,
00055     MB_TYPE_8x8     | MB_TYPE_L0,
00056     MB_TYPE_16x16   | MB_TYPE_L0,
00057     MB_TYPE_16x16   | MB_TYPE_L1,
00058     MB_TYPE_SKIP,
00059     MB_TYPE_DIRECT2 | MB_TYPE_16x16,
00060     MB_TYPE_16x8    | MB_TYPE_L0,
00061     MB_TYPE_8x16    | MB_TYPE_L0,
00062     MB_TYPE_16x16   | MB_TYPE_L0L1,
00063     MB_TYPE_16x16   | MB_TYPE_L0    | MB_TYPE_SEPARATE_DC
00064 };
00065 
00066 
00067 static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];
00068 
00069 static int rv34_decode_mv(RV34DecContext *r, int block_type);
00070 
00076 static const int table_offs[] = {
00077       0,   1818,   3622,   4144,   4698,   5234,   5804,   5868,   5900,   5932,
00078    5996,   6252,   6316,   6348,   6380,   7674,   8944,  10274,  11668,  12250,
00079   14060,  15846,  16372,  16962,  17512,  18148,  18180,  18212,  18244,  18308,
00080   18564,  18628,  18660,  18692,  20036,  21314,  22648,  23968,  24614,  26384,
00081   28190,  28736,  29366,  29938,  30608,  30640,  30672,  30704,  30768,  31024,
00082   31088,  31120,  31184,  32570,  33898,  35236,  36644,  37286,  39020,  40802,
00083   41368,  42052,  42692,  43348,  43380,  43412,  43444,  43476,  43604,  43668,
00084   43700,  43732,  45100,  46430,  47778,  49160,  49802,  51550,  53340,  53972,
00085   54648,  55348,  55994,  56122,  56154,  56186,  56218,  56346,  56410,  56442,
00086   56474,  57878,  59290,  60636,  62036,  62682,  64460,  64524,  64588,  64716,
00087   64844,  66076,  67466,  67978,  68542,  69064,  69648,  70296,  72010,  72074,
00088   72138,  72202,  72330,  73572,  74936,  75454,  76030,  76566,  77176,  77822,
00089   79582,  79646,  79678,  79742,  79870,  81180,  82536,  83064,  83672,  84242,
00090   84934,  85576,  87384,  87448,  87480,  87544,  87672,  88982,  90340,  90902,
00091   91598,  92182,  92846,  93488,  95246,  95278,  95310,  95374,  95502,  96878,
00092   98266,  98848,  99542, 100234, 100884, 101524, 103320, 103352, 103384, 103416,
00093  103480, 104874, 106222, 106910, 107584, 108258, 108902, 109544, 111366, 111398,
00094  111430, 111462, 111494, 112878, 114320, 114988, 115660, 116310, 116950, 117592
00095 };
00096 
00097 static VLC_TYPE table_data[117592][2];
00098 
00107 static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms,
00108                          const int num)
00109 {
00110     int i;
00111     int counts[17] = {0}, codes[17];
00112     uint16_t cw[MAX_VLC_SIZE], syms[MAX_VLC_SIZE];
00113     uint8_t bits2[MAX_VLC_SIZE];
00114     int maxbits = 0, realsize = 0;
00115 
00116     for(i = 0; i < size; i++){
00117         if(bits[i]){
00118             bits2[realsize] = bits[i];
00119             syms[realsize] = insyms ? insyms[i] : i;
00120             realsize++;
00121             maxbits = FFMAX(maxbits, bits[i]);
00122             counts[bits[i]]++;
00123         }
00124     }
00125 
00126     codes[0] = 0;
00127     for(i = 0; i < 16; i++)
00128         codes[i+1] = (codes[i] + counts[i]) << 1;
00129     for(i = 0; i < realsize; i++)
00130         cw[i] = codes[bits2[i]]++;
00131 
00132     vlc->table = &table_data[table_offs[num]];
00133     vlc->table_allocated = table_offs[num + 1] - table_offs[num];
00134     init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize,
00135                     bits2, 1, 1,
00136                     cw,    2, 2,
00137                     syms,  2, 2, INIT_VLC_USE_NEW_STATIC);
00138 }
00139 
00143 static av_cold void rv34_init_tables(void)
00144 {
00145     int i, j, k;
00146 
00147     for(i = 0; i < NUM_INTRA_TABLES; i++){
00148         for(j = 0; j < 2; j++){
00149             rv34_gen_vlc(rv34_table_intra_cbppat   [i][j], CBPPAT_VLC_SIZE,   &intra_vlcs[i].cbppattern[j],     NULL, 19*i + 0 + j);
00150             rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j], NULL, 19*i + 2 + j);
00151             rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j],  NULL, 19*i + 4 + j);
00152             for(k = 0; k < 4; k++){
00153                 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);
00154             }
00155         }
00156         for(j = 0; j < 4; j++){
00157             rv34_gen_vlc(rv34_table_intra_firstpat[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j], NULL, 19*i + 14 + j);
00158         }
00159         rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL, 19*i + 18);
00160     }
00161 
00162     for(i = 0; i < NUM_INTER_TABLES; i++){
00163         rv34_gen_vlc(rv34_inter_cbppat[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0], NULL, i*12 + 95);
00164         for(j = 0; j < 4; j++){
00165             rv34_gen_vlc(rv34_inter_cbp[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j], rv34_cbp_code, i*12 + 96 + j);
00166         }
00167         for(j = 0; j < 2; j++){
00168             rv34_gen_vlc(rv34_table_inter_firstpat [i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j],  NULL, i*12 + 100 + j);
00169             rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j], NULL, i*12 + 102 + j);
00170             rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j],  NULL, i*12 + 104 + j);
00171         }
00172         rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL, i*12 + 106);
00173     }
00174 }
00175  // vlc group
00177 
00186 static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table)
00187 {
00188     int pattern, code, cbp=0;
00189     int ones;
00190     static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000};
00191     static const int shifts[4] = { 0, 2, 8, 10 };
00192     const int *curshift = shifts;
00193     int i, t, mask;
00194 
00195     code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2);
00196     pattern = code & 0xF;
00197     code >>= 4;
00198 
00199     ones = rv34_count_ones[pattern];
00200 
00201     for(mask = 8; mask; mask >>= 1, curshift++){
00202         if(pattern & mask)
00203             cbp |= get_vlc2(gb, vlc->cbp[table][ones].table, vlc->cbp[table][ones].bits, 1) << curshift[0];
00204     }
00205 
00206     for(i = 0; i < 4; i++){
00207         t = (modulo_three_table[code] >> (6 - 2*i)) & 3;
00208         if(t == 1)
00209             cbp |= cbp_masks[get_bits1(gb)] << i;
00210         if(t == 2)
00211             cbp |= cbp_masks[2] << i;
00212     }
00213     return cbp;
00214 }
00215 
00219 static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc, int q)
00220 {
00221     if(coef){
00222         if(coef == esc){
00223             coef = get_vlc2(gb, vlc->table, 9, 2);
00224             if(coef > 23){
00225                 coef -= 23;
00226                 coef = 22 + ((1 << coef) | get_bits(gb, coef));
00227             }
00228             coef += esc;
00229         }
00230         if(get_bits1(gb))
00231             coef = -coef;
00232         *dst = (coef*q + 8) >> 4;
00233     }
00234 }
00235 
00239 static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, int q)
00240 {
00241     int flags = modulo_three_table[code];
00242 
00243     decode_coeff(    dst+0*4+0, (flags >> 6)    , 3, gb, vlc, q);
00244     if(is_block2){
00245         decode_coeff(dst+1*4+0, (flags >> 4) & 3, 2, gb, vlc, q);
00246         decode_coeff(dst+0*4+1, (flags >> 2) & 3, 2, gb, vlc, q);
00247     }else{
00248         decode_coeff(dst+0*4+1, (flags >> 4) & 3, 2, gb, vlc, q);
00249         decode_coeff(dst+1*4+0, (flags >> 2) & 3, 2, gb, vlc, q);
00250     }
00251     decode_coeff(    dst+1*4+1, (flags >> 0) & 3, 2, gb, vlc, q);
00252 }
00253 
00257 static inline void decode_subblock1(DCTELEM *dst, int code, GetBitContext *gb, VLC *vlc, int q)
00258 {
00259     int coeff = modulo_three_table[code] >> 6;
00260     decode_coeff(dst, coeff, 3, gb, vlc, q);
00261 }
00262 
00263 static inline void decode_subblock3(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc,
00264                                     int q_dc, int q_ac1, int q_ac2)
00265 {
00266     int flags = modulo_three_table[code];
00267 
00268     decode_coeff(    dst+0*4+0, (flags >> 6)    , 3, gb, vlc, q_dc);
00269     if(is_block2){
00270         decode_coeff(dst+1*4+0, (flags >> 4) & 3, 2, gb, vlc, q_ac1);
00271         decode_coeff(dst+0*4+1, (flags >> 2) & 3, 2, gb, vlc, q_ac1);
00272     }else{
00273         decode_coeff(dst+0*4+1, (flags >> 4) & 3, 2, gb, vlc, q_ac1);
00274         decode_coeff(dst+1*4+0, (flags >> 2) & 3, 2, gb, vlc, q_ac1);
00275     }
00276     decode_coeff(    dst+1*4+1, (flags >> 0) & 3, 2, gb, vlc, q_ac2);
00277 }
00278 
00290 static inline int rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc, int q_dc, int q_ac1, int q_ac2)
00291 {
00292     int code, pattern, has_ac = 1;
00293 
00294     code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2);
00295 
00296     pattern = code & 0x7;
00297 
00298     code >>= 3;
00299 
00300     if (modulo_three_table[code] & 0x3F) {
00301         decode_subblock3(dst, code, 0, gb, &rvlc->coefficient, q_dc, q_ac1, q_ac2);
00302     } else {
00303         decode_subblock1(dst, code, gb, &rvlc->coefficient, q_dc);
00304         if (!pattern)
00305             return 0;
00306         has_ac = 0;
00307     }
00308 
00309     if(pattern & 4){
00310         code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
00311         decode_subblock(dst + 4*0+2, code, 0, gb, &rvlc->coefficient, q_ac2);
00312     }
00313     if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block
00314         code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
00315         decode_subblock(dst + 4*2+0, code, 1, gb, &rvlc->coefficient, q_ac2);
00316     }
00317     if(pattern & 1){
00318         code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
00319         decode_subblock(dst + 4*2+2, code, 0, gb, &rvlc->coefficient, q_ac2);
00320     }
00321     return has_ac || pattern;
00322 }
00323 
00333 int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size)
00334 {
00335     int i;
00336     for(i = 0; i < 5; i++)
00337         if(rv34_mb_max_sizes[i] >= mb_size - 1)
00338             break;
00339     return rv34_mb_bits_sizes[i];
00340 }
00341 
00345 static inline RV34VLC* choose_vlc_set(int quant, int mod, int type)
00346 {
00347     if(mod == 2 && quant < 19) quant += 10;
00348     else if(mod && quant < 26) quant += 5;
00349     return type ? &inter_vlcs[rv34_quant_to_vlc_set[1][av_clip(quant, 0, 30)]]
00350                 : &intra_vlcs[rv34_quant_to_vlc_set[0][av_clip(quant, 0, 30)]];
00351 }
00352 
00356 static int rv34_decode_intra_mb_header(RV34DecContext *r, int8_t *intra_types)
00357 {
00358     MpegEncContext *s = &r->s;
00359     GetBitContext *gb = &s->gb;
00360     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
00361     int t;
00362 
00363     r->is16 = get_bits1(gb);
00364     if(r->is16){
00365         s->current_picture_ptr->f.mb_type[mb_pos] = MB_TYPE_INTRA16x16;
00366         r->block_type = RV34_MB_TYPE_INTRA16x16;
00367         t = get_bits(gb, 2);
00368         fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
00369         r->luma_vlc   = 2;
00370     }else{
00371         if(!r->rv30){
00372             if(!get_bits1(gb))
00373                 av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
00374         }
00375         s->current_picture_ptr->f.mb_type[mb_pos] = MB_TYPE_INTRA;
00376         r->block_type = RV34_MB_TYPE_INTRA;
00377         if(r->decode_intra_types(r, gb, intra_types) < 0)
00378             return -1;
00379         r->luma_vlc   = 1;
00380     }
00381 
00382     r->chroma_vlc = 0;
00383     r->cur_vlcs   = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
00384 
00385     return rv34_decode_cbp(gb, r->cur_vlcs, r->is16);
00386 }
00387 
00391 static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types)
00392 {
00393     MpegEncContext *s = &r->s;
00394     GetBitContext *gb = &s->gb;
00395     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
00396     int i, t;
00397 
00398     r->block_type = r->decode_mb_info(r);
00399     if(r->block_type == -1)
00400         return -1;
00401     s->current_picture_ptr->f.mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
00402     r->mb_type[mb_pos] = r->block_type;
00403     if(r->block_type == RV34_MB_SKIP){
00404         if(s->pict_type == AV_PICTURE_TYPE_P)
00405             r->mb_type[mb_pos] = RV34_MB_P_16x16;
00406         if(s->pict_type == AV_PICTURE_TYPE_B)
00407             r->mb_type[mb_pos] = RV34_MB_B_DIRECT;
00408     }
00409     r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->f.mb_type[mb_pos]);
00410     rv34_decode_mv(r, r->block_type);
00411     if(r->block_type == RV34_MB_SKIP){
00412         fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0]));
00413         return 0;
00414     }
00415     r->chroma_vlc = 1;
00416     r->luma_vlc   = 0;
00417 
00418     if(IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])){
00419         if(r->is16){
00420             t = get_bits(gb, 2);
00421             fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
00422             r->luma_vlc   = 2;
00423         }else{
00424             if(r->decode_intra_types(r, gb, intra_types) < 0)
00425                 return -1;
00426             r->luma_vlc   = 1;
00427         }
00428         r->chroma_vlc = 0;
00429         r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
00430     }else{
00431         for(i = 0; i < 16; i++)
00432             intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0;
00433         r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
00434         if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){
00435             r->is16 = 1;
00436             r->chroma_vlc = 1;
00437             r->luma_vlc   = 2;
00438             r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
00439         }
00440     }
00441 
00442     return rv34_decode_cbp(gb, r->cur_vlcs, r->is16);
00443 }
00444  //bitstream functions
00446 
00453 static const uint8_t part_sizes_w[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2 };
00454 
00456 static const uint8_t part_sizes_h[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2 };
00457 
00459 static const uint8_t avail_indexes[4] = { 6, 7, 10, 11 };
00460 
00468 static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int dmv_no)
00469 {
00470     MpegEncContext *s = &r->s;
00471     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00472     int A[2] = {0}, B[2], C[2];
00473     int i, j;
00474     int mx, my;
00475     int avail_index = avail_indexes[subblock_no];
00476     int c_off = part_sizes_w[block_type];
00477 
00478     mv_pos += (subblock_no & 1) + (subblock_no >> 1)*s->b8_stride;
00479     if(subblock_no == 3)
00480         c_off = -1;
00481 
00482     if(r->avail_cache[avail_index - 1]){
00483         A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][0];
00484         A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][1];
00485     }
00486     if(r->avail_cache[avail_index - 4]){
00487         B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][0];
00488         B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][1];
00489     }else{
00490         B[0] = A[0];
00491         B[1] = A[1];
00492     }
00493     if(!r->avail_cache[avail_index - 4 + c_off]){
00494         if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1] || r->rv30)){
00495             C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][0];
00496             C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][1];
00497         }else{
00498             C[0] = A[0];
00499             C[1] = A[1];
00500         }
00501     }else{
00502         C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][0];
00503         C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][1];
00504     }
00505     mx = mid_pred(A[0], B[0], C[0]);
00506     my = mid_pred(A[1], B[1], C[1]);
00507     mx += r->dmv[dmv_no][0];
00508     my += r->dmv[dmv_no][1];
00509     for(j = 0; j < part_sizes_h[block_type]; j++){
00510         for(i = 0; i < part_sizes_w[block_type]; i++){
00511             s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
00512             s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
00513         }
00514     }
00515 }
00516 
00517 #define GET_PTS_DIFF(a, b) ((a - b + 8192) & 0x1FFF)
00518 
00522 static int calc_add_mv(RV34DecContext *r, int dir, int val)
00523 {
00524     int mul = dir ? -r->weight2 : r->weight1;
00525 
00526     return (val * mul + 0x2000) >> 14;
00527 }
00528 
00532 static inline void rv34_pred_b_vector(int A[2], int B[2], int C[2],
00533                                       int A_avail, int B_avail, int C_avail,
00534                                       int *mx, int *my)
00535 {
00536     if(A_avail + B_avail + C_avail != 3){
00537         *mx = A[0] + B[0] + C[0];
00538         *my = A[1] + B[1] + C[1];
00539         if(A_avail + B_avail + C_avail == 2){
00540             *mx /= 2;
00541             *my /= 2;
00542         }
00543     }else{
00544         *mx = mid_pred(A[0], B[0], C[0]);
00545         *my = mid_pred(A[1], B[1], C[1]);
00546     }
00547 }
00548 
00552 static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
00553 {
00554     MpegEncContext *s = &r->s;
00555     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
00556     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00557     int A[2], B[2], C[2];
00558     int has_A = 0, has_B = 0, has_C = 0;
00559     int mx, my;
00560     int i, j;
00561     Picture *cur_pic = s->current_picture_ptr;
00562     const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0;
00563     int type = cur_pic->f.mb_type[mb_pos];
00564 
00565     memset(A, 0, sizeof(A));
00566     memset(B, 0, sizeof(B));
00567     memset(C, 0, sizeof(C));
00568     if((r->avail_cache[6-1] & type) & mask){
00569         A[0] = cur_pic->f.motion_val[dir][mv_pos - 1][0];
00570         A[1] = cur_pic->f.motion_val[dir][mv_pos - 1][1];
00571         has_A = 1;
00572     }
00573     if((r->avail_cache[6-4] & type) & mask){
00574         B[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][0];
00575         B[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][1];
00576         has_B = 1;
00577     }
00578     if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){
00579         C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][0];
00580         C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][1];
00581         has_C = 1;
00582     }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){
00583         C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][0];
00584         C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][1];
00585         has_C = 1;
00586     }
00587 
00588     rv34_pred_b_vector(A, B, C, has_A, has_B, has_C, &mx, &my);
00589 
00590     mx += r->dmv[dir][0];
00591     my += r->dmv[dir][1];
00592 
00593     for(j = 0; j < 2; j++){
00594         for(i = 0; i < 2; i++){
00595             cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
00596             cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
00597         }
00598     }
00599     if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){
00600         ZERO8x2(cur_pic->f.motion_val[!dir][mv_pos], s->b8_stride);
00601     }
00602 }
00603 
00607 static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
00608 {
00609     MpegEncContext *s = &r->s;
00610     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00611     int A[2] = {0}, B[2], C[2];
00612     int i, j, k;
00613     int mx, my;
00614     int avail_index = avail_indexes[0];
00615 
00616     if(r->avail_cache[avail_index - 1]){
00617         A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][0];
00618         A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][1];
00619     }
00620     if(r->avail_cache[avail_index - 4]){
00621         B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][0];
00622         B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][1];
00623     }else{
00624         B[0] = A[0];
00625         B[1] = A[1];
00626     }
00627     if(!r->avail_cache[avail_index - 4 + 2]){
00628         if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1])){
00629             C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][0];
00630             C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][1];
00631         }else{
00632             C[0] = A[0];
00633             C[1] = A[1];
00634         }
00635     }else{
00636         C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][0];
00637         C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][1];
00638     }
00639     mx = mid_pred(A[0], B[0], C[0]);
00640     my = mid_pred(A[1], B[1], C[1]);
00641     mx += r->dmv[0][0];
00642     my += r->dmv[0][1];
00643     for(j = 0; j < 2; j++){
00644         for(i = 0; i < 2; i++){
00645             for(k = 0; k < 2; k++){
00646                 s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
00647                 s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
00648             }
00649         }
00650     }
00651 }
00652 
00653 static const int chroma_coeffs[3] = { 0, 3, 5 };
00654 
00670 static inline void rv34_mc(RV34DecContext *r, const int block_type,
00671                           const int xoff, const int yoff, int mv_off,
00672                           const int width, const int height, int dir,
00673                           const int thirdpel, int weighted,
00674                           qpel_mc_func (*qpel_mc)[16],
00675                           h264_chroma_mc_func (*chroma_mc))
00676 {
00677     MpegEncContext *s = &r->s;
00678     uint8_t *Y, *U, *V, *srcY, *srcU, *srcV;
00679     int dxy, mx, my, umx, umy, lx, ly, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
00680     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + mv_off;
00681     int is16x16 = 1;
00682 
00683     if(thirdpel){
00684         int chroma_mx, chroma_my;
00685         mx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
00686         my = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
00687         lx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
00688         ly = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
00689         chroma_mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2;
00690         chroma_my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2;
00691         umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24);
00692         umy = (chroma_my + (3 << 24)) / 3 - (1 << 24);
00693         uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3];
00694         uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3];
00695     }else{
00696         int cx, cy;
00697         mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] >> 2;
00698         my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] >> 2;
00699         lx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] & 3;
00700         ly = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] & 3;
00701         cx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2;
00702         cy = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2;
00703         umx = cx >> 2;
00704         umy = cy >> 2;
00705         uvmx = (cx & 3) << 1;
00706         uvmy = (cy & 3) << 1;
00707         //due to some flaw RV40 uses the same MC compensation routine for H2V2 and H3V3
00708         if(uvmx == 6 && uvmy == 6)
00709             uvmx = uvmy = 4;
00710     }
00711 
00712     if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
00713         /* wait for the referenced mb row to be finished */
00714         int mb_row = FFMIN(s->mb_height - 1,
00715                            s->mb_y + ((yoff + my + 5 + 8 * height) >> 4));
00716         AVFrame *f = dir ? &s->next_picture_ptr->f : &s->last_picture_ptr->f;
00717         ff_thread_await_progress(f, mb_row, 0);
00718     }
00719 
00720     dxy = ly*4 + lx;
00721     srcY = dir ? s->next_picture_ptr->f.data[0] : s->last_picture_ptr->f.data[0];
00722     srcU = dir ? s->next_picture_ptr->f.data[1] : s->last_picture_ptr->f.data[1];
00723     srcV = dir ? s->next_picture_ptr->f.data[2] : s->last_picture_ptr->f.data[2];
00724     src_x = s->mb_x * 16 + xoff + mx;
00725     src_y = s->mb_y * 16 + yoff + my;
00726     uvsrc_x = s->mb_x * 8 + (xoff >> 1) + umx;
00727     uvsrc_y = s->mb_y * 8 + (yoff >> 1) + umy;
00728     srcY += src_y * s->linesize + src_x;
00729     srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
00730     srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
00731     if(s->h_edge_pos - (width << 3) < 6 || s->v_edge_pos - (height << 3) < 6 ||
00732        (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4 ||
00733        (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4) {
00734         uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize;
00735 
00736         srcY -= 2 + 2*s->linesize;
00737         s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6,
00738                             src_x - 2, src_y - 2, s->h_edge_pos, s->v_edge_pos);
00739         srcY = s->edge_emu_buffer + 2 + 2*s->linesize;
00740         s->dsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1,
00741                             uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
00742         s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1,
00743                             uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
00744         srcU = uvbuf;
00745         srcV = uvbuf + 16;
00746     }
00747     if(!weighted){
00748         Y = s->dest[0] + xoff      + yoff     *s->linesize;
00749         U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
00750         V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
00751     }else{
00752         Y = r->tmp_b_block_y [dir]     +  xoff     +  yoff    *s->linesize;
00753         U = r->tmp_b_block_uv[dir*2]   + (xoff>>1) + (yoff>>1)*s->uvlinesize;
00754         V = r->tmp_b_block_uv[dir*2+1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
00755     }
00756 
00757     if(block_type == RV34_MB_P_16x8){
00758         qpel_mc[1][dxy](Y, srcY, s->linesize);
00759         Y    += 8;
00760         srcY += 8;
00761     }else if(block_type == RV34_MB_P_8x16){
00762         qpel_mc[1][dxy](Y, srcY, s->linesize);
00763         Y    += 8 * s->linesize;
00764         srcY += 8 * s->linesize;
00765     }
00766     is16x16 = (block_type != RV34_MB_P_8x8) && (block_type != RV34_MB_P_16x8) && (block_type != RV34_MB_P_8x16);
00767     qpel_mc[!is16x16][dxy](Y, srcY, s->linesize);
00768     chroma_mc[2-width]   (U, srcU, s->uvlinesize, height*4, uvmx, uvmy);
00769     chroma_mc[2-width]   (V, srcV, s->uvlinesize, height*4, uvmx, uvmy);
00770 }
00771 
00772 static void rv34_mc_1mv(RV34DecContext *r, const int block_type,
00773                         const int xoff, const int yoff, int mv_off,
00774                         const int width, const int height, int dir)
00775 {
00776     rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30, 0,
00777             r->rdsp.put_pixels_tab,
00778             r->rdsp.put_chroma_pixels_tab);
00779 }
00780 
00781 static void rv4_weight(RV34DecContext *r)
00782 {
00783     r->rdsp.rv40_weight_pixels_tab[0](r->s.dest[0],
00784                                       r->tmp_b_block_y[0],
00785                                       r->tmp_b_block_y[1],
00786                                       r->weight1,
00787                                       r->weight2,
00788                                       r->s.linesize);
00789     r->rdsp.rv40_weight_pixels_tab[1](r->s.dest[1],
00790                                       r->tmp_b_block_uv[0],
00791                                       r->tmp_b_block_uv[2],
00792                                       r->weight1,
00793                                       r->weight2,
00794                                       r->s.uvlinesize);
00795     r->rdsp.rv40_weight_pixels_tab[1](r->s.dest[2],
00796                                       r->tmp_b_block_uv[1],
00797                                       r->tmp_b_block_uv[3],
00798                                       r->weight1,
00799                                       r->weight2,
00800                                       r->s.uvlinesize);
00801 }
00802 
00803 static void rv34_mc_2mv(RV34DecContext *r, const int block_type)
00804 {
00805     int weighted = !r->rv30 && block_type != RV34_MB_B_BIDIR && r->weight1 != 8192;
00806 
00807     rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30, weighted,
00808             r->rdsp.put_pixels_tab,
00809             r->rdsp.put_chroma_pixels_tab);
00810     if(!weighted){
00811         rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 0,
00812                 r->rdsp.avg_pixels_tab,
00813                 r->rdsp.avg_chroma_pixels_tab);
00814     }else{
00815         rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 1,
00816                 r->rdsp.put_pixels_tab,
00817                 r->rdsp.put_chroma_pixels_tab);
00818         rv4_weight(r);
00819     }
00820 }
00821 
00822 static void rv34_mc_2mv_skip(RV34DecContext *r)
00823 {
00824     int i, j;
00825     int weighted = !r->rv30 && r->weight1 != 8192;
00826 
00827     for(j = 0; j < 2; j++)
00828         for(i = 0; i < 2; i++){
00829              rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30,
00830                      weighted,
00831                      r->rdsp.put_pixels_tab,
00832                      r->rdsp.put_chroma_pixels_tab);
00833              rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30,
00834                      weighted,
00835                      weighted ? r->rdsp.put_pixels_tab : r->rdsp.avg_pixels_tab,
00836                      weighted ? r->rdsp.put_chroma_pixels_tab : r->rdsp.avg_chroma_pixels_tab);
00837         }
00838     if(weighted)
00839         rv4_weight(r);
00840 }
00841 
00843 static const int num_mvs[RV34_MB_TYPES] = { 0, 0, 1, 4, 1, 1, 0, 0, 2, 2, 2, 1 };
00844 
00849 static int rv34_decode_mv(RV34DecContext *r, int block_type)
00850 {
00851     MpegEncContext *s = &r->s;
00852     GetBitContext *gb = &s->gb;
00853     int i, j, k, l;
00854     int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
00855     int next_bt;
00856 
00857     memset(r->dmv, 0, sizeof(r->dmv));
00858     for(i = 0; i < num_mvs[block_type]; i++){
00859         r->dmv[i][0] = svq3_get_se_golomb(gb);
00860         r->dmv[i][1] = svq3_get_se_golomb(gb);
00861     }
00862     switch(block_type){
00863     case RV34_MB_TYPE_INTRA:
00864     case RV34_MB_TYPE_INTRA16x16:
00865         ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00866         return 0;
00867     case RV34_MB_SKIP:
00868         if(s->pict_type == AV_PICTURE_TYPE_P){
00869             ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00870             rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
00871             break;
00872         }
00873     case RV34_MB_B_DIRECT:
00874         //surprisingly, it uses motion scheme from next reference frame
00875         /* wait for the current mb row to be finished */
00876         if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
00877             ff_thread_await_progress(&s->next_picture_ptr->f, FFMAX(0, s->mb_y-1), 0);
00878 
00879         next_bt = s->next_picture_ptr->f.mb_type[s->mb_x + s->mb_y * s->mb_stride];
00880         if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){
00881             ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00882             ZERO8x2(s->current_picture_ptr->f.motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00883         }else
00884             for(j = 0; j < 2; j++)
00885                 for(i = 0; i < 2; i++)
00886                     for(k = 0; k < 2; k++)
00887                         for(l = 0; l < 2; l++)
00888                             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]);
00889         if(!(IS_16X8(next_bt) || IS_8X16(next_bt) || IS_8X8(next_bt))) //we can use whole macroblock MC
00890             rv34_mc_2mv(r, block_type);
00891         else
00892             rv34_mc_2mv_skip(r);
00893         ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
00894         break;
00895     case RV34_MB_P_16x16:
00896     case RV34_MB_P_MIX16x16:
00897         rv34_pred_mv(r, block_type, 0, 0);
00898         rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
00899         break;
00900     case RV34_MB_B_FORWARD:
00901     case RV34_MB_B_BACKWARD:
00902         r->dmv[1][0] = r->dmv[0][0];
00903         r->dmv[1][1] = r->dmv[0][1];
00904         if(r->rv30)
00905             rv34_pred_mv_rv3(r, block_type, block_type == RV34_MB_B_BACKWARD);
00906         else
00907             rv34_pred_mv_b  (r, block_type, block_type == RV34_MB_B_BACKWARD);
00908         rv34_mc_1mv     (r, block_type, 0, 0, 0, 2, 2, block_type == RV34_MB_B_BACKWARD);
00909         break;
00910     case RV34_MB_P_16x8:
00911     case RV34_MB_P_8x16:
00912         rv34_pred_mv(r, block_type, 0, 0);
00913         rv34_pred_mv(r, block_type, 1 + (block_type == RV34_MB_P_16x8), 1);
00914         if(block_type == RV34_MB_P_16x8){
00915             rv34_mc_1mv(r, block_type, 0, 0, 0,            2, 1, 0);
00916             rv34_mc_1mv(r, block_type, 0, 8, s->b8_stride, 2, 1, 0);
00917         }
00918         if(block_type == RV34_MB_P_8x16){
00919             rv34_mc_1mv(r, block_type, 0, 0, 0, 1, 2, 0);
00920             rv34_mc_1mv(r, block_type, 8, 0, 1, 1, 2, 0);
00921         }
00922         break;
00923     case RV34_MB_B_BIDIR:
00924         rv34_pred_mv_b  (r, block_type, 0);
00925         rv34_pred_mv_b  (r, block_type, 1);
00926         rv34_mc_2mv     (r, block_type);
00927         break;
00928     case RV34_MB_P_8x8:
00929         for(i=0;i< 4;i++){
00930             rv34_pred_mv(r, block_type, i, i);
00931             rv34_mc_1mv (r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1, 0);
00932         }
00933         break;
00934     }
00935 
00936     return 0;
00937 } // mv group
00939 
00945 static const int ittrans[9] = {
00946  DC_PRED, VERT_PRED, HOR_PRED, DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_LEFT_PRED,
00947  VERT_RIGHT_PRED, VERT_LEFT_PRED, HOR_UP_PRED, HOR_DOWN_PRED,
00948 };
00949 
00951 static const int ittrans16[4] = {
00952  DC_PRED8x8, VERT_PRED8x8, HOR_PRED8x8, PLANE_PRED8x8,
00953 };
00954 
00958 static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int itype, int up, int left, int down, int right)
00959 {
00960     uint8_t *prev = dst - stride + 4;
00961     uint32_t topleft;
00962 
00963     if(!up && !left)
00964         itype = DC_128_PRED;
00965     else if(!up){
00966         if(itype == VERT_PRED) itype = HOR_PRED;
00967         if(itype == DC_PRED)   itype = LEFT_DC_PRED;
00968     }else if(!left){
00969         if(itype == HOR_PRED)  itype = VERT_PRED;
00970         if(itype == DC_PRED)   itype = TOP_DC_PRED;
00971         if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
00972     }
00973     if(!down){
00974         if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
00975         if(itype == HOR_UP_PRED) itype = HOR_UP_PRED_RV40_NODOWN;
00976         if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN;
00977     }
00978     if(!right && up){
00979         topleft = dst[-stride + 3] * 0x01010101u;
00980         prev = (uint8_t*)&topleft;
00981     }
00982     r->h.pred4x4[itype](dst, prev, stride);
00983 }
00984 
00985 static inline int adjust_pred16(int itype, int up, int left)
00986 {
00987     if(!up && !left)
00988         itype = DC_128_PRED8x8;
00989     else if(!up){
00990         if(itype == PLANE_PRED8x8)itype = HOR_PRED8x8;
00991         if(itype == VERT_PRED8x8) itype = HOR_PRED8x8;
00992         if(itype == DC_PRED8x8)   itype = LEFT_DC_PRED8x8;
00993     }else if(!left){
00994         if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8;
00995         if(itype == HOR_PRED8x8)  itype = VERT_PRED8x8;
00996         if(itype == DC_PRED8x8)   itype = TOP_DC_PRED8x8;
00997     }
00998     return itype;
00999 }
01000 
01001 static inline void rv34_process_block(RV34DecContext *r,
01002                                       uint8_t *pdst, int stride,
01003                                       int fc, int sc, int q_dc, int q_ac)
01004 {
01005     MpegEncContext *s = &r->s;
01006     DCTELEM *ptr = s->block[0];
01007     int has_ac = rv34_decode_block(ptr, &s->gb, r->cur_vlcs,
01008                                    fc, sc, q_dc, q_ac, q_ac);
01009     if(has_ac){
01010         r->rdsp.rv34_idct_add(pdst, stride, ptr);
01011     }else{
01012         r->rdsp.rv34_idct_dc_add(pdst, stride, ptr[0]);
01013         ptr[0] = 0;
01014     }
01015 }
01016 
01017 static void rv34_output_i16x16(RV34DecContext *r, int8_t *intra_types, int cbp)
01018 {
01019     LOCAL_ALIGNED_16(DCTELEM, block16, [16]);
01020     MpegEncContext *s    = &r->s;
01021     GetBitContext  *gb   = &s->gb;
01022     int             q_dc = rv34_qscale_tab[ r->luma_dc_quant_i[s->qscale] ],
01023                     q_ac = rv34_qscale_tab[s->qscale];
01024     uint8_t        *dst  = s->dest[0];
01025     DCTELEM        *ptr  = s->block[0];
01026     int       avail[6*8] = {0};
01027     int i, j, itype, has_ac;
01028 
01029     memset(block16, 0, 16 * sizeof(*block16));
01030 
01031     // Set neighbour information.
01032     if(r->avail_cache[1])
01033         avail[0] = 1;
01034     if(r->avail_cache[2])
01035         avail[1] = avail[2] = 1;
01036     if(r->avail_cache[3])
01037         avail[3] = avail[4] = 1;
01038     if(r->avail_cache[4])
01039         avail[5] = 1;
01040     if(r->avail_cache[5])
01041         avail[8] = avail[16] = 1;
01042     if(r->avail_cache[9])
01043         avail[24] = avail[32] = 1;
01044 
01045     has_ac = rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac);
01046     if(has_ac)
01047         r->rdsp.rv34_inv_transform(block16);
01048     else
01049         r->rdsp.rv34_inv_transform_dc(block16);
01050 
01051     itype = ittrans16[intra_types[0]];
01052     itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
01053     r->h.pred16x16[itype](dst, s->linesize);
01054 
01055     for(j = 0; j < 4; j++){
01056         for(i = 0; i < 4; i++, cbp >>= 1){
01057             int dc = block16[i + j*4];
01058 
01059             if(cbp & 1){
01060                 has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
01061             }else
01062                 has_ac = 0;
01063 
01064             if(has_ac){
01065                 ptr[0] = dc;
01066                 r->rdsp.rv34_idct_add(dst+4*i, s->linesize, ptr);
01067             }else
01068                 r->rdsp.rv34_idct_dc_add(dst+4*i, s->linesize, dc);
01069         }
01070 
01071         dst += 4*s->linesize;
01072     }
01073 
01074     itype = ittrans16[intra_types[0]];
01075     if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
01076     itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
01077 
01078     q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
01079     q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
01080 
01081     for(j = 1; j < 3; j++){
01082         dst = s->dest[j];
01083         r->h.pred8x8[itype](dst, s->uvlinesize);
01084         for(i = 0; i < 4; i++, cbp >>= 1){
01085             uint8_t *pdst;
01086             if(!(cbp & 1)) continue;
01087             pdst   = dst + (i&1)*4 + (i&2)*2*s->uvlinesize;
01088 
01089             rv34_process_block(r, pdst, s->uvlinesize,
01090                                r->chroma_vlc, 1, q_dc, q_ac);
01091         }
01092     }
01093 }
01094 
01095 static void rv34_output_intra(RV34DecContext *r, int8_t *intra_types, int cbp)
01096 {
01097     MpegEncContext *s   = &r->s;
01098     uint8_t        *dst = s->dest[0];
01099     int      avail[6*8] = {0};
01100     int i, j, k;
01101     int idx, q_ac, q_dc;
01102 
01103     // Set neighbour information.
01104     if(r->avail_cache[1])
01105         avail[0] = 1;
01106     if(r->avail_cache[2])
01107         avail[1] = avail[2] = 1;
01108     if(r->avail_cache[3])
01109         avail[3] = avail[4] = 1;
01110     if(r->avail_cache[4])
01111         avail[5] = 1;
01112     if(r->avail_cache[5])
01113         avail[8] = avail[16] = 1;
01114     if(r->avail_cache[9])
01115         avail[24] = avail[32] = 1;
01116 
01117     q_ac = rv34_qscale_tab[s->qscale];
01118     for(j = 0; j < 4; j++){
01119         idx = 9 + j*8;
01120         for(i = 0; i < 4; i++, cbp >>= 1, dst += 4, idx++){
01121             rv34_pred_4x4_block(r, dst, s->linesize, ittrans[intra_types[i]], avail[idx-8], avail[idx-1], avail[idx+7], avail[idx-7]);
01122             avail[idx] = 1;
01123             if(!(cbp & 1)) continue;
01124 
01125             rv34_process_block(r, dst, s->linesize,
01126                                r->luma_vlc, 0, q_ac, q_ac);
01127         }
01128         dst += s->linesize * 4 - 4*4;
01129         intra_types += r->intra_types_stride;
01130     }
01131 
01132     intra_types -= r->intra_types_stride * 4;
01133 
01134     q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
01135     q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
01136 
01137     for(k = 0; k < 2; k++){
01138         dst = s->dest[1+k];
01139         fill_rectangle(r->avail_cache + 6, 2, 2, 4, 0, 4);
01140 
01141         for(j = 0; j < 2; j++){
01142             int* acache = r->avail_cache + 6 + j*4;
01143             for(i = 0; i < 2; i++, cbp >>= 1, acache++){
01144                 int itype = ittrans[intra_types[i*2+j*2*r->intra_types_stride]];
01145                 rv34_pred_4x4_block(r, dst+4*i, s->uvlinesize, itype, acache[-4], acache[-1], !i && !j, acache[-3]);
01146                 acache[0] = 1;
01147 
01148                 if(!(cbp&1)) continue;
01149 
01150                 rv34_process_block(r, dst + 4*i, s->uvlinesize,
01151                                    r->chroma_vlc, 1, q_dc, q_ac);
01152             }
01153 
01154             dst += 4*s->uvlinesize;
01155         }
01156     }
01157 }
01158 
01159 static int is_mv_diff_gt_3(int16_t (*motion_val)[2], int step)
01160 {
01161     int d;
01162     d = motion_val[0][0] - motion_val[-step][0];
01163     if(d < -3 || d > 3)
01164         return 1;
01165     d = motion_val[0][1] - motion_val[-step][1];
01166     if(d < -3 || d > 3)
01167         return 1;
01168     return 0;
01169 }
01170 
01171 static int rv34_set_deblock_coef(RV34DecContext *r)
01172 {
01173     MpegEncContext *s = &r->s;
01174     int hmvmask = 0, vmvmask = 0, i, j;
01175     int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
01176     int16_t (*motion_val)[2] = &s->current_picture_ptr->f.motion_val[0][midx];
01177     for(j = 0; j < 16; j += 8){
01178         for(i = 0; i < 2; i++){
01179             if(is_mv_diff_gt_3(motion_val + i, 1))
01180                 vmvmask |= 0x11 << (j + i*2);
01181             if((j || s->mb_y) && is_mv_diff_gt_3(motion_val + i, s->b8_stride))
01182                 hmvmask |= 0x03 << (j + i*2);
01183         }
01184         motion_val += s->b8_stride;
01185     }
01186     if(s->first_slice_line)
01187         hmvmask &= ~0x000F;
01188     if(!s->mb_x)
01189         vmvmask &= ~0x1111;
01190     if(r->rv30){ //RV30 marks both subblocks on the edge for filtering
01191         vmvmask |= (vmvmask & 0x4444) >> 1;
01192         hmvmask |= (hmvmask & 0x0F00) >> 4;
01193         if(s->mb_x)
01194             r->deblock_coefs[s->mb_x - 1 + s->mb_y*s->mb_stride] |= (vmvmask & 0x1111) << 3;
01195         if(!s->first_slice_line)
01196             r->deblock_coefs[s->mb_x + (s->mb_y - 1)*s->mb_stride] |= (hmvmask & 0xF) << 12;
01197     }
01198     return hmvmask | vmvmask;
01199 }
01200 
01201 static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types)
01202 {
01203     MpegEncContext *s   = &r->s;
01204     GetBitContext  *gb  = &s->gb;
01205     uint8_t        *dst = s->dest[0];
01206     DCTELEM        *ptr = s->block[0];
01207     int          mb_pos = s->mb_x + s->mb_y * s->mb_stride;
01208     int cbp, cbp2;
01209     int q_dc, q_ac, has_ac;
01210     int i, j;
01211     int dist;
01212 
01213     // Calculate which neighbours are available. Maybe it's worth optimizing too.
01214     memset(r->avail_cache, 0, sizeof(r->avail_cache));
01215     fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4);
01216     dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
01217     if(s->mb_x && dist)
01218         r->avail_cache[5] =
01219         r->avail_cache[9] = s->current_picture_ptr->f.mb_type[mb_pos - 1];
01220     if(dist >= s->mb_width)
01221         r->avail_cache[2] =
01222         r->avail_cache[3] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride];
01223     if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
01224         r->avail_cache[4] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride + 1];
01225     if(s->mb_x && dist > s->mb_width)
01226         r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1];
01227 
01228     s->qscale = r->si.quant;
01229     cbp = cbp2 = rv34_decode_inter_mb_header(r, intra_types);
01230     r->cbp_luma  [mb_pos] = cbp;
01231     r->cbp_chroma[mb_pos] = cbp >> 16;
01232     r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos];
01233     s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale;
01234 
01235     if(cbp == -1)
01236         return -1;
01237 
01238     if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])){
01239         if(r->is16) rv34_output_i16x16(r, intra_types, cbp);
01240         else        rv34_output_intra(r, intra_types, cbp);
01241         return 0;
01242     }
01243 
01244     if(r->is16){
01245         // Only for RV34_MB_P_MIX16x16
01246         LOCAL_ALIGNED_16(DCTELEM, block16, [16]);
01247         memset(block16, 0, 16 * sizeof(*block16));
01248         q_dc = rv34_qscale_tab[ r->luma_dc_quant_p[s->qscale] ];
01249         q_ac = rv34_qscale_tab[s->qscale];
01250         if (rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac))
01251             r->rdsp.rv34_inv_transform(block16);
01252         else
01253             r->rdsp.rv34_inv_transform_dc(block16);
01254 
01255         q_ac = rv34_qscale_tab[s->qscale];
01256 
01257         for(j = 0; j < 4; j++){
01258             for(i = 0; i < 4; i++, cbp >>= 1){
01259                 int      dc   = block16[i + j*4];
01260 
01261                 if(cbp & 1){
01262                     has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
01263                 }else
01264                     has_ac = 0;
01265 
01266                 if(has_ac){
01267                     ptr[0] = dc;
01268                     r->rdsp.rv34_idct_add(dst+4*i, s->linesize, ptr);
01269                 }else
01270                     r->rdsp.rv34_idct_dc_add(dst+4*i, s->linesize, dc);
01271             }
01272 
01273             dst += 4*s->linesize;
01274         }
01275 
01276         r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
01277     }else{
01278         q_ac = rv34_qscale_tab[s->qscale];
01279 
01280         for(j = 0; j < 4; j++){
01281             for(i = 0; i < 4; i++, cbp >>= 1){
01282                 if(!(cbp & 1)) continue;
01283 
01284                 rv34_process_block(r, dst + 4*i, s->linesize,
01285                                    r->luma_vlc, 0, q_ac, q_ac);
01286             }
01287             dst += 4*s->linesize;
01288         }
01289     }
01290 
01291     q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
01292     q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
01293 
01294     for(j = 1; j < 3; j++){
01295         dst = s->dest[j];
01296         for(i = 0; i < 4; i++, cbp >>= 1){
01297             uint8_t *pdst;
01298             if(!(cbp & 1)) continue;
01299             pdst = dst + (i&1)*4 + (i&2)*2*s->uvlinesize;
01300 
01301             rv34_process_block(r, pdst, s->uvlinesize,
01302                                r->chroma_vlc, 1, q_dc, q_ac);
01303         }
01304     }
01305 
01306     return 0;
01307 }
01308 
01309 static int rv34_decode_intra_macroblock(RV34DecContext *r, int8_t *intra_types)
01310 {
01311     MpegEncContext *s = &r->s;
01312     int cbp, dist;
01313     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
01314 
01315     // Calculate which neighbours are available. Maybe it's worth optimizing too.
01316     memset(r->avail_cache, 0, sizeof(r->avail_cache));
01317     fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4);
01318     dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
01319     if(s->mb_x && dist)
01320         r->avail_cache[5] =
01321         r->avail_cache[9] = s->current_picture_ptr->f.mb_type[mb_pos - 1];
01322     if(dist >= s->mb_width)
01323         r->avail_cache[2] =
01324         r->avail_cache[3] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride];
01325     if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
01326         r->avail_cache[4] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride + 1];
01327     if(s->mb_x && dist > s->mb_width)
01328         r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1];
01329 
01330     s->qscale = r->si.quant;
01331     cbp = rv34_decode_intra_mb_header(r, intra_types);
01332     r->cbp_luma  [mb_pos] = cbp;
01333     r->cbp_chroma[mb_pos] = cbp >> 16;
01334     r->deblock_coefs[mb_pos] = 0xFFFF;
01335     s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale;
01336 
01337     if(cbp == -1)
01338         return -1;
01339 
01340     if(r->is16){
01341         rv34_output_i16x16(r, intra_types, cbp);
01342         return 0;
01343     }
01344 
01345     rv34_output_intra(r, intra_types, cbp);
01346     return 0;
01347 }
01348 
01349 static int check_slice_end(RV34DecContext *r, MpegEncContext *s)
01350 {
01351     int bits;
01352     if(s->mb_y >= s->mb_height)
01353         return 1;
01354     if(!s->mb_num_left)
01355         return 1;
01356     if(r->s.mb_skip_run > 1)
01357         return 0;
01358     bits = get_bits_left(&s->gb);
01359     if(bits < 0 || (bits < 8 && !show_bits(&s->gb, bits)))
01360         return 1;
01361     return 0;
01362 }
01363 
01364 static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int buf_size)
01365 {
01366     MpegEncContext *s = &r->s;
01367     GetBitContext *gb = &s->gb;
01368     int mb_pos;
01369     int res;
01370 
01371     init_get_bits(&r->s.gb, buf, buf_size*8);
01372     res = r->parse_slice_header(r, gb, &r->si);
01373     if(res < 0){
01374         av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n");
01375         return -1;
01376     }
01377 
01378     if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
01379         if(s->width != r->si.width || s->height != r->si.height){
01380             av_log(s->avctx, AV_LOG_DEBUG, "Changing dimensions to %dx%d\n", r->si.width,r->si.height);
01381             MPV_common_end(s);
01382             s->width  = r->si.width;
01383             s->height = r->si.height;
01384             avcodec_set_dimensions(s->avctx, s->width, s->height);
01385             if(MPV_common_init(s) < 0)
01386                 return -1;
01387             r->intra_types_stride = s->mb_width*4 + 4;
01388             r->intra_types_hist = av_realloc(r->intra_types_hist, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
01389             r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;
01390             r->mb_type = av_realloc(r->mb_type, r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type));
01391             r->cbp_luma   = av_realloc(r->cbp_luma,   r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma));
01392             r->cbp_chroma = av_realloc(r->cbp_chroma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma));
01393             r->deblock_coefs = av_realloc(r->deblock_coefs, r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs));
01394             av_freep(&r->tmp_b_block_base);
01395         }
01396         s->pict_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
01397         if(MPV_frame_start(s, s->avctx) < 0)
01398             return -1;
01399         ff_er_frame_start(s);
01400         if (!r->tmp_b_block_base) {
01401             int i;
01402 
01403             r->tmp_b_block_base = av_malloc(s->linesize * 48);
01404             for (i = 0; i < 2; i++)
01405                 r->tmp_b_block_y[i] = r->tmp_b_block_base + i * 16 * s->linesize;
01406             for (i = 0; i < 4; i++)
01407                 r->tmp_b_block_uv[i] = r->tmp_b_block_base + 32 * s->linesize
01408                                        + (i >> 1) * 8 * s->uvlinesize + (i & 1) * 16;
01409         }
01410         r->cur_pts = r->si.pts;
01411         if(s->pict_type != AV_PICTURE_TYPE_B){
01412             r->last_pts = r->next_pts;
01413             r->next_pts = r->cur_pts;
01414         }else{
01415             int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
01416             int dist0   = GET_PTS_DIFF(r->cur_pts,  r->last_pts);
01417             int dist1   = GET_PTS_DIFF(r->next_pts, r->cur_pts);
01418 
01419             if(!refdist){
01420                 r->weight1 = r->weight2 = 8192;
01421             }else{
01422                 r->weight1 = (dist0 << 14) / refdist;
01423                 r->weight2 = (dist1 << 14) / refdist;
01424             }
01425         }
01426         s->mb_x = s->mb_y = 0;
01427         ff_thread_finish_setup(s->avctx);
01428     } else {
01429         int slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
01430 
01431         if (slice_type != s->pict_type) {
01432             av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
01433             return AVERROR_INVALIDDATA;
01434         }
01435     }
01436 
01437     r->si.end = end;
01438     s->qscale = r->si.quant;
01439     s->mb_num_left = r->si.end - r->si.start;
01440     r->s.mb_skip_run = 0;
01441 
01442     mb_pos = s->mb_x + s->mb_y * s->mb_width;
01443     if(r->si.start != mb_pos){
01444         av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->si.start, mb_pos);
01445         s->mb_x = r->si.start % s->mb_width;
01446         s->mb_y = r->si.start / s->mb_width;
01447     }
01448     memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
01449     s->first_slice_line = 1;
01450     s->resync_mb_x = s->mb_x;
01451     s->resync_mb_y = s->mb_y;
01452 
01453     ff_init_block_index(s);
01454     while(!check_slice_end(r, s)) {
01455         ff_update_block_index(s);
01456 
01457         if(r->si.type)
01458             res = rv34_decode_inter_macroblock(r, r->intra_types + s->mb_x * 4 + 4);
01459         else
01460             res = rv34_decode_intra_macroblock(r, r->intra_types + s->mb_x * 4 + 4);
01461         if(res < 0){
01462             ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_ERROR);
01463             return -1;
01464         }
01465         if (++s->mb_x == s->mb_width) {
01466             s->mb_x = 0;
01467             s->mb_y++;
01468             ff_init_block_index(s);
01469 
01470             memmove(r->intra_types_hist, r->intra_types, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));
01471             memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));
01472 
01473             if(r->loop_filter && s->mb_y >= 2)
01474                 r->loop_filter(r, s->mb_y - 2);
01475 
01476             if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
01477                 ff_thread_report_progress(&s->current_picture_ptr->f,
01478                                           s->mb_y - 2, 0);
01479 
01480         }
01481         if(s->mb_x == s->resync_mb_x)
01482             s->first_slice_line=0;
01483         s->mb_num_left--;
01484     }
01485     ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
01486 
01487     return s->mb_y == s->mb_height;
01488 }
01489  // recons group end
01491 
01495 av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
01496 {
01497     RV34DecContext *r = avctx->priv_data;
01498     MpegEncContext *s = &r->s;
01499 
01500     MPV_decode_defaults(s);
01501     s->avctx      = avctx;
01502     s->out_format = FMT_H263;
01503     s->codec_id   = avctx->codec_id;
01504 
01505     s->width  = avctx->width;
01506     s->height = avctx->height;
01507 
01508     r->s.avctx = avctx;
01509     avctx->flags |= CODEC_FLAG_EMU_EDGE;
01510     r->s.flags |= CODEC_FLAG_EMU_EDGE;
01511     avctx->pix_fmt = PIX_FMT_YUV420P;
01512     avctx->has_b_frames = 1;
01513     s->low_delay = 0;
01514 
01515     if (MPV_common_init(s) < 0)
01516         return -1;
01517 
01518     ff_h264_pred_init(&r->h, CODEC_ID_RV40, 8, 1);
01519 
01520 #if CONFIG_RV30_DECODER
01521     if (avctx->codec_id == CODEC_ID_RV30)
01522         ff_rv30dsp_init(&r->rdsp, &r->s.dsp);
01523 #endif
01524 #if CONFIG_RV40_DECODER
01525     if (avctx->codec_id == CODEC_ID_RV40)
01526         ff_rv40dsp_init(&r->rdsp, &r->s.dsp);
01527 #endif
01528 
01529     r->intra_types_stride = 4*s->mb_stride + 4;
01530     r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
01531     r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;
01532 
01533     r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type));
01534 
01535     r->cbp_luma   = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma));
01536     r->cbp_chroma = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma));
01537     r->deblock_coefs = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs));
01538 
01539     if(!intra_vlcs[0].cbppattern[0].bits)
01540         rv34_init_tables();
01541 
01542     return 0;
01543 }
01544 
01545 int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx)
01546 {
01547     RV34DecContext *r = avctx->priv_data;
01548 
01549     r->s.avctx = avctx;
01550 
01551     if (avctx->internal->is_copy) {
01552         r->cbp_chroma       = av_malloc(r->s.mb_stride * r->s.mb_height *
01553                                         sizeof(*r->cbp_chroma));
01554         r->cbp_luma         = av_malloc(r->s.mb_stride * r->s.mb_height *
01555                                         sizeof(*r->cbp_luma));
01556         r->deblock_coefs    = av_malloc(r->s.mb_stride * r->s.mb_height *
01557                                         sizeof(*r->deblock_coefs));
01558         r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 *
01559                                         sizeof(*r->intra_types_hist));
01560         r->mb_type          = av_malloc(r->s.mb_stride * r->s.mb_height *
01561                                         sizeof(*r->mb_type));
01562 
01563         if (!(r->cbp_chroma       && r->cbp_luma && r->deblock_coefs &&
01564               r->intra_types_hist && r->mb_type)) {
01565             av_freep(&r->cbp_chroma);
01566             av_freep(&r->cbp_luma);
01567             av_freep(&r->deblock_coefs);
01568             av_freep(&r->intra_types_hist);
01569             av_freep(&r->mb_type);
01570             r->intra_types = NULL;
01571             return AVERROR(ENOMEM);
01572         }
01573 
01574         r->intra_types      = r->intra_types_hist + r->intra_types_stride * 4;
01575         r->tmp_b_block_base = NULL;
01576 
01577         memset(r->mb_type, 0,  r->s.mb_stride * r->s.mb_height *
01578                sizeof(*r->mb_type));
01579 
01580         MPV_common_init(&r->s);
01581     }
01582     return 0;
01583 }
01584 
01585 int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
01586 {
01587     RV34DecContext *r = dst->priv_data, *r1 = src->priv_data;
01588     MpegEncContext * const s = &r->s, * const s1 = &r1->s;
01589     int err;
01590 
01591     if (dst == src || !s1->context_initialized)
01592         return 0;
01593 
01594     if ((err = ff_mpeg_update_thread_context(dst, src)))
01595         return err;
01596 
01597     r->cur_pts  = r1->cur_pts;
01598     r->last_pts = r1->last_pts;
01599     r->next_pts = r1->next_pts;
01600 
01601     memset(&r->si, 0, sizeof(r->si));
01602 
01603     /* necessary since it is it the condition checked for in decode_slice
01604      * to call MPV_frame_start. cmp. comment at the end of decode_frame */
01605     s->current_picture_ptr = NULL;
01606 
01607     return 0;
01608 }
01609 
01610 static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n)
01611 {
01612     if(avctx->slice_count) return avctx->slice_offset[n];
01613     else                   return AV_RL32(buf + n*8 - 4) == 1 ? AV_RL32(buf + n*8) :  AV_RB32(buf + n*8);
01614 }
01615 
01616 int ff_rv34_decode_frame(AVCodecContext *avctx,
01617                             void *data, int *data_size,
01618                             AVPacket *avpkt)
01619 {
01620     const uint8_t *buf = avpkt->data;
01621     int buf_size = avpkt->size;
01622     RV34DecContext *r = avctx->priv_data;
01623     MpegEncContext *s = &r->s;
01624     AVFrame *pict = data;
01625     SliceInfo si;
01626     int i;
01627     int slice_count;
01628     const uint8_t *slices_hdr = NULL;
01629     int last = 0;
01630 
01631     /* no supplementary picture */
01632     if (buf_size == 0) {
01633         /* special case for last picture */
01634         if (s->low_delay==0 && s->next_picture_ptr) {
01635             *pict = *(AVFrame*)s->next_picture_ptr;
01636             s->next_picture_ptr = NULL;
01637 
01638             *data_size = sizeof(AVFrame);
01639         }
01640         return 0;
01641     }
01642 
01643     if(!avctx->slice_count){
01644         slice_count = (*buf++) + 1;
01645         slices_hdr = buf + 4;
01646         buf += 8 * slice_count;
01647         buf_size -= 1 + 8 * slice_count;
01648     }else
01649         slice_count = avctx->slice_count;
01650 
01651     //parse first slice header to check whether this frame can be decoded
01652     if(get_slice_offset(avctx, slices_hdr, 0) < 0 ||
01653        get_slice_offset(avctx, slices_hdr, 0) > buf_size){
01654         av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
01655         return -1;
01656     }
01657     init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), (buf_size-get_slice_offset(avctx, slices_hdr, 0))*8);
01658     if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){
01659         av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");
01660         return -1;
01661     }
01662     if ((!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) && si.type == AV_PICTURE_TYPE_B)
01663         return -1;
01664     if(   (avctx->skip_frame >= AVDISCARD_NONREF && si.type==AV_PICTURE_TYPE_B)
01665        || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=AV_PICTURE_TYPE_I)
01666        ||  avctx->skip_frame >= AVDISCARD_ALL)
01667         return avpkt->size;
01668 
01669     for(i = 0; i < slice_count; i++){
01670         int offset = get_slice_offset(avctx, slices_hdr, i);
01671         int size;
01672         if(i+1 == slice_count)
01673             size = buf_size - offset;
01674         else
01675             size = get_slice_offset(avctx, slices_hdr, i+1) - offset;
01676 
01677         if(offset < 0 || offset > buf_size){
01678             av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
01679             break;
01680         }
01681 
01682         r->si.end = s->mb_width * s->mb_height;
01683         if(i+1 < slice_count){
01684             if (get_slice_offset(avctx, slices_hdr, i+1) < 0 ||
01685                 get_slice_offset(avctx, slices_hdr, i+1) > buf_size) {
01686                 av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
01687                 break;
01688             }
01689             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);
01690             if(r->parse_slice_header(r, &r->s.gb, &si) < 0){
01691                 if(i+2 < slice_count)
01692                     size = get_slice_offset(avctx, slices_hdr, i+2) - offset;
01693                 else
01694                     size = buf_size - offset;
01695             }else
01696                 r->si.end = si.start;
01697         }
01698         if (size < 0 || size > buf_size - offset) {
01699             av_log(avctx, AV_LOG_ERROR, "Slice size is invalid\n");
01700             break;
01701         }
01702         last = rv34_decode_slice(r, r->si.end, buf + offset, size);
01703         s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;
01704         if(last)
01705             break;
01706     }
01707 
01708     if(last && s->current_picture_ptr){
01709         if(r->loop_filter)
01710             r->loop_filter(r, s->mb_height - 1);
01711         if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
01712             ff_thread_report_progress(&s->current_picture_ptr->f,
01713                                       s->mb_height - 1, 0);
01714         ff_er_frame_end(s);
01715         MPV_frame_end(s);
01716         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
01717             *pict = *(AVFrame*)s->current_picture_ptr;
01718         } else if (s->last_picture_ptr != NULL) {
01719             *pict = *(AVFrame*)s->last_picture_ptr;
01720         }
01721 
01722         if(s->last_picture_ptr || s->low_delay){
01723             *data_size = sizeof(AVFrame);
01724             ff_print_debug_info(s, pict);
01725         }
01726         s->current_picture_ptr = NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
01727     }
01728     return avpkt->size;
01729 }
01730 
01731 av_cold int ff_rv34_decode_end(AVCodecContext *avctx)
01732 {
01733     RV34DecContext *r = avctx->priv_data;
01734 
01735     MPV_common_end(&r->s);
01736 
01737     av_freep(&r->intra_types_hist);
01738     r->intra_types = NULL;
01739     av_freep(&r->tmp_b_block_base);
01740     av_freep(&r->mb_type);
01741     av_freep(&r->cbp_luma);
01742     av_freep(&r->cbp_chroma);
01743     av_freep(&r->deblock_coefs);
01744 
01745     return 0;
01746 }
Generated on Sun Apr 22 2012 21:54:04 for Libav by doxygen 1.7.1