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