00001 /* 00002 * RV40 decoder 00003 * Copyright (c) 2007 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 00032 #include "rv34.h" 00033 #include "rv40vlc2.h" 00034 #include "rv40data.h" 00035 00036 static VLC aic_top_vlc; 00037 static VLC aic_mode1_vlc[AIC_MODE1_NUM], aic_mode2_vlc[AIC_MODE2_NUM]; 00038 static VLC ptype_vlc[NUM_PTYPE_VLCS], btype_vlc[NUM_BTYPE_VLCS]; 00039 00043 static av_cold void rv40_init_tables(void) 00044 { 00045 int i; 00046 00047 init_vlc(&aic_top_vlc, AIC_TOP_BITS, AIC_TOP_SIZE, 00048 rv40_aic_top_vlc_bits, 1, 1, 00049 rv40_aic_top_vlc_codes, 1, 1, INIT_VLC_USE_STATIC); 00050 for(i = 0; i < AIC_MODE1_NUM; i++){ 00051 // Every tenth VLC table is empty 00052 if((i % 10) == 9) continue; 00053 init_vlc(&aic_mode1_vlc[i], AIC_MODE1_BITS, AIC_MODE1_SIZE, 00054 aic_mode1_vlc_bits[i], 1, 1, 00055 aic_mode1_vlc_codes[i], 1, 1, INIT_VLC_USE_STATIC); 00056 } 00057 for(i = 0; i < AIC_MODE2_NUM; i++){ 00058 init_vlc(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE, 00059 aic_mode2_vlc_bits[i], 1, 1, 00060 aic_mode2_vlc_codes[i], 2, 2, INIT_VLC_USE_STATIC); 00061 } 00062 for(i = 0; i < NUM_PTYPE_VLCS; i++) 00063 init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE, 00064 ptype_vlc_bits[i], 1, 1, 00065 ptype_vlc_codes[i], 1, 1, 00066 ptype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC); 00067 for(i = 0; i < NUM_BTYPE_VLCS; i++) 00068 init_vlc_sparse(&btype_vlc[i], BTYPE_VLC_BITS, BTYPE_VLC_SIZE, 00069 btype_vlc_bits[i], 1, 1, 00070 btype_vlc_codes[i], 1, 1, 00071 btype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC); 00072 } 00073 00080 static int get_dimension(GetBitContext *gb, const int *dim) 00081 { 00082 int t = get_bits(gb, 3); 00083 int val = dim[t]; 00084 if(val < 0) 00085 val = dim[get_bits1(gb) - val]; 00086 if(!val){ 00087 do{ 00088 t = get_bits(gb, 8); 00089 val += t << 2; 00090 }while(t == 0xFF); 00091 } 00092 return val; 00093 } 00094 00098 static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h) 00099 { 00100 *w = get_dimension(gb, rv40_standard_widths); 00101 *h = get_dimension(gb, rv40_standard_heights); 00102 } 00103 00104 static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si) 00105 { 00106 int mb_bits; 00107 int w = r->s.width, h = r->s.height; 00108 int mb_size; 00109 00110 memset(si, 0, sizeof(SliceInfo)); 00111 if(get_bits1(gb)) 00112 return -1; 00113 si->type = get_bits(gb, 2); 00114 if(si->type == 1) si->type = 0; 00115 si->quant = get_bits(gb, 5); 00116 if(get_bits(gb, 2)) 00117 return -1; 00118 si->vlc_set = get_bits(gb, 2); 00119 skip_bits1(gb); 00120 si->pts = get_bits(gb, 13); 00121 if(!si->type || !get_bits1(gb)) 00122 rv40_parse_picture_size(gb, &w, &h); 00123 if(avcodec_check_dimensions(r->s.avctx, w, h) < 0) 00124 return -1; 00125 si->width = w; 00126 si->height = h; 00127 mb_size = ((w + 15) >> 4) * ((h + 15) >> 4); 00128 mb_bits = ff_rv34_get_start_offset(gb, mb_size); 00129 si->start = get_bits(gb, mb_bits); 00130 00131 return 0; 00132 } 00133 00137 static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t *dst) 00138 { 00139 MpegEncContext *s = &r->s; 00140 int i, j, k, v; 00141 int A, B, C; 00142 int pattern; 00143 int8_t *ptr; 00144 00145 for(i = 0; i < 4; i++, dst += s->b4_stride){ 00146 if(!i && s->first_slice_line){ 00147 pattern = get_vlc2(gb, aic_top_vlc.table, AIC_TOP_BITS, 1); 00148 dst[0] = (pattern >> 2) & 2; 00149 dst[1] = (pattern >> 1) & 2; 00150 dst[2] = pattern & 2; 00151 dst[3] = (pattern << 1) & 2; 00152 continue; 00153 } 00154 ptr = dst; 00155 for(j = 0; j < 4; j++){ 00156 /* Coefficients are read using VLC chosen by the prediction pattern 00157 * The first one (used for retrieving a pair of coefficients) is 00158 * constructed from the top, top right and left coefficients 00159 * The second one (used for retrieving only one coefficient) is 00160 * top + 10 * left. 00161 */ 00162 A = ptr[-s->b4_stride + 1]; // it won't be used for the last coefficient in a row 00163 B = ptr[-s->b4_stride]; 00164 C = ptr[-1]; 00165 pattern = A + (B << 4) + (C << 8); 00166 for(k = 0; k < MODE2_PATTERNS_NUM; k++) 00167 if(pattern == rv40_aic_table_index[k]) 00168 break; 00169 if(j < 3 && k < MODE2_PATTERNS_NUM){ //pattern is found, decoding 2 coefficients 00170 v = get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2); 00171 *ptr++ = v/9; 00172 *ptr++ = v%9; 00173 j++; 00174 }else{ 00175 if(B != -1 && C != -1) 00176 v = get_vlc2(gb, aic_mode1_vlc[B + C*10].table, AIC_MODE1_BITS, 1); 00177 else{ // tricky decoding 00178 v = 0; 00179 switch(C){ 00180 case -1: // code 0 -> 1, 1 -> 0 00181 if(B < 2) 00182 v = get_bits1(gb) ^ 1; 00183 break; 00184 case 0: 00185 case 2: // code 0 -> 2, 1 -> 0 00186 v = (get_bits1(gb) ^ 1) << 1; 00187 break; 00188 } 00189 } 00190 *ptr++ = v; 00191 } 00192 } 00193 } 00194 return 0; 00195 } 00196 00200 static int rv40_decode_mb_info(RV34DecContext *r) 00201 { 00202 MpegEncContext *s = &r->s; 00203 GetBitContext *gb = &s->gb; 00204 int q, i; 00205 int prev_type = 0; 00206 int mb_pos = s->mb_x + s->mb_y * s->mb_stride; 00207 int blocks[RV34_MB_TYPES] = {0}; 00208 int count = 0; 00209 00210 if(!r->s.mb_skip_run) { 00211 r->s.mb_skip_run = svq3_get_ue_golomb(gb) + 1; 00212 if(r->s.mb_skip_run > (unsigned)s->mb_num) 00213 return -1; 00214 } 00215 00216 if(--r->s.mb_skip_run) 00217 return RV34_MB_SKIP; 00218 00219 if(r->avail_cache[5-1]) 00220 blocks[r->mb_type[mb_pos - 1]]++; 00221 if(r->avail_cache[5-4]){ 00222 blocks[r->mb_type[mb_pos - s->mb_stride]]++; 00223 if(r->avail_cache[5-2]) 00224 blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++; 00225 if(r->avail_cache[5-5]) 00226 blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++; 00227 } 00228 00229 for(i = 0; i < RV34_MB_TYPES; i++){ 00230 if(blocks[i] > count){ 00231 count = blocks[i]; 00232 prev_type = i; 00233 } 00234 } 00235 if(s->pict_type == FF_P_TYPE){ 00236 prev_type = block_num_to_ptype_vlc_num[prev_type]; 00237 q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); 00238 if(q < PBTYPE_ESCAPE) 00239 return q; 00240 q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); 00241 av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n"); 00242 }else{ 00243 prev_type = block_num_to_btype_vlc_num[prev_type]; 00244 q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); 00245 if(q < PBTYPE_ESCAPE) 00246 return q; 00247 q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); 00248 av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n"); 00249 } 00250 return 0; 00251 } 00252 00253 #define CLIP_SYMM(a, b) av_clip(a, -(b), b) 00254 00257 static inline void rv40_weak_loop_filter(uint8_t *src, const int step, 00258 const int filter_p1, const int filter_q1, 00259 const int alpha, const int beta, 00260 const int lim_p0q0, 00261 const int lim_q1, const int lim_p1, 00262 const int diff_p1p0, const int diff_q1q0, 00263 const int diff_p1p2, const int diff_q1q2) 00264 { 00265 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; 00266 int t, u, diff; 00267 00268 t = src[0*step] - src[-1*step]; 00269 if(!t) 00270 return; 00271 u = (alpha * FFABS(t)) >> 7; 00272 if(u > 3 - (filter_p1 && filter_q1)) 00273 return; 00274 00275 t <<= 2; 00276 if(filter_p1 && filter_q1) 00277 t += src[-2*step] - src[1*step]; 00278 diff = CLIP_SYMM((t + 4) >> 3, lim_p0q0); 00279 src[-1*step] = cm[src[-1*step] + diff]; 00280 src[ 0*step] = cm[src[ 0*step] - diff]; 00281 if(FFABS(diff_p1p2) <= beta && filter_p1){ 00282 t = (diff_p1p0 + diff_p1p2 - diff) >> 1; 00283 src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim_p1)]; 00284 } 00285 if(FFABS(diff_q1q2) <= beta && filter_q1){ 00286 t = (diff_q1q0 + diff_q1q2 + diff) >> 1; 00287 src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim_q1)]; 00288 } 00289 } 00290 00291 static inline void rv40_adaptive_loop_filter(uint8_t *src, const int step, 00292 const int stride, const int dmode, 00293 const int lim_q1, const int lim_p1, 00294 const int alpha, 00295 const int beta, const int beta2, 00296 const int chroma, const int edge) 00297 { 00298 int diff_p1p0[4], diff_q1q0[4], diff_p1p2[4], diff_q1q2[4]; 00299 int sum_p1p0 = 0, sum_q1q0 = 0, sum_p1p2 = 0, sum_q1q2 = 0; 00300 uint8_t *ptr; 00301 int flag_strong0 = 1, flag_strong1 = 1; 00302 int filter_p1, filter_q1; 00303 int i; 00304 int lims; 00305 00306 for(i = 0, ptr = src; i < 4; i++, ptr += stride){ 00307 diff_p1p0[i] = ptr[-2*step] - ptr[-1*step]; 00308 diff_q1q0[i] = ptr[ 1*step] - ptr[ 0*step]; 00309 sum_p1p0 += diff_p1p0[i]; 00310 sum_q1q0 += diff_q1q0[i]; 00311 } 00312 filter_p1 = FFABS(sum_p1p0) < (beta<<2); 00313 filter_q1 = FFABS(sum_q1q0) < (beta<<2); 00314 if(!filter_p1 && !filter_q1) 00315 return; 00316 00317 for(i = 0, ptr = src; i < 4; i++, ptr += stride){ 00318 diff_p1p2[i] = ptr[-2*step] - ptr[-3*step]; 00319 diff_q1q2[i] = ptr[ 1*step] - ptr[ 2*step]; 00320 sum_p1p2 += diff_p1p2[i]; 00321 sum_q1q2 += diff_q1q2[i]; 00322 } 00323 00324 if(edge){ 00325 flag_strong0 = filter_p1 && (FFABS(sum_p1p2) < beta2); 00326 flag_strong1 = filter_q1 && (FFABS(sum_q1q2) < beta2); 00327 }else{ 00328 flag_strong0 = flag_strong1 = 0; 00329 } 00330 00331 lims = filter_p1 + filter_q1 + ((lim_q1 + lim_p1) >> 1) + 1; 00332 if(flag_strong0 && flag_strong1){ /* strong filtering */ 00333 for(i = 0; i < 4; i++, src += stride){ 00334 int sflag, p0, q0, p1, q1; 00335 int t = src[0*step] - src[-1*step]; 00336 00337 if(!t) continue; 00338 sflag = (alpha * FFABS(t)) >> 7; 00339 if(sflag > 1) continue; 00340 00341 p0 = (25*src[-3*step] + 26*src[-2*step] 00342 + 26*src[-1*step] 00343 + 26*src[ 0*step] + 25*src[ 1*step] + rv40_dither_l[dmode + i]) >> 7; 00344 q0 = (25*src[-2*step] + 26*src[-1*step] 00345 + 26*src[ 0*step] 00346 + 26*src[ 1*step] + 25*src[ 2*step] + rv40_dither_r[dmode + i]) >> 7; 00347 if(sflag){ 00348 p0 = av_clip(p0, src[-1*step] - lims, src[-1*step] + lims); 00349 q0 = av_clip(q0, src[ 0*step] - lims, src[ 0*step] + lims); 00350 } 00351 p1 = (25*src[-4*step] + 26*src[-3*step] 00352 + 26*src[-2*step] 00353 + 26*p0 + 25*src[ 0*step] + rv40_dither_l[dmode + i]) >> 7; 00354 q1 = (25*src[-1*step] + 26*q0 00355 + 26*src[ 1*step] 00356 + 26*src[ 2*step] + 25*src[ 3*step] + rv40_dither_r[dmode + i]) >> 7; 00357 if(sflag){ 00358 p1 = av_clip(p1, src[-2*step] - lims, src[-2*step] + lims); 00359 q1 = av_clip(q1, src[ 1*step] - lims, src[ 1*step] + lims); 00360 } 00361 src[-2*step] = p1; 00362 src[-1*step] = p0; 00363 src[ 0*step] = q0; 00364 src[ 1*step] = q1; 00365 if(!chroma){ 00366 src[-3*step] = (25*src[-1*step] + 26*src[-2*step] + 51*src[-3*step] + 26*src[-4*step] + 64) >> 7; 00367 src[ 2*step] = (25*src[ 0*step] + 26*src[ 1*step] + 51*src[ 2*step] + 26*src[ 3*step] + 64) >> 7; 00368 } 00369 } 00370 }else if(filter_p1 && filter_q1){ 00371 for(i = 0; i < 4; i++, src += stride) 00372 rv40_weak_loop_filter(src, step, 1, 1, alpha, beta, lims, lim_q1, lim_p1, 00373 diff_p1p0[i], diff_q1q0[i], diff_p1p2[i], diff_q1q2[i]); 00374 }else{ 00375 for(i = 0; i < 4; i++, src += stride) 00376 rv40_weak_loop_filter(src, step, filter_p1, filter_q1, 00377 alpha, beta, lims>>1, lim_q1>>1, lim_p1>>1, 00378 diff_p1p0[i], diff_q1q0[i], diff_p1p2[i], diff_q1q2[i]); 00379 } 00380 } 00381 00382 static void rv40_v_loop_filter(uint8_t *src, int stride, int dmode, 00383 int lim_q1, int lim_p1, 00384 int alpha, int beta, int beta2, int chroma, int edge){ 00385 rv40_adaptive_loop_filter(src, 1, stride, dmode, lim_q1, lim_p1, 00386 alpha, beta, beta2, chroma, edge); 00387 } 00388 static void rv40_h_loop_filter(uint8_t *src, int stride, int dmode, 00389 int lim_q1, int lim_p1, 00390 int alpha, int beta, int beta2, int chroma, int edge){ 00391 rv40_adaptive_loop_filter(src, stride, 1, dmode, lim_q1, lim_p1, 00392 alpha, beta, beta2, chroma, edge); 00393 } 00394 00395 enum RV40BlockPos{ 00396 POS_CUR, 00397 POS_TOP, 00398 POS_LEFT, 00399 POS_BOTTOM, 00400 }; 00401 00402 #define MASK_CUR 0x0001 00403 #define MASK_RIGHT 0x0008 00404 #define MASK_BOTTOM 0x0010 00405 #define MASK_TOP 0x1000 00406 #define MASK_Y_TOP_ROW 0x000F 00407 #define MASK_Y_LAST_ROW 0xF000 00408 #define MASK_Y_LEFT_COL 0x1111 00409 #define MASK_Y_RIGHT_COL 0x8888 00410 #define MASK_C_TOP_ROW 0x0003 00411 #define MASK_C_LAST_ROW 0x000C 00412 #define MASK_C_LEFT_COL 0x0005 00413 #define MASK_C_RIGHT_COL 0x000A 00414 00415 static const int neighbour_offs_x[4] = { 0, 0, -1, 0 }; 00416 static const int neighbour_offs_y[4] = { 0, -1, 0, 1 }; 00417 00421 static void rv40_loop_filter(RV34DecContext *r, int row) 00422 { 00423 MpegEncContext *s = &r->s; 00424 int mb_pos, mb_x; 00425 int i, j, k; 00426 uint8_t *Y, *C; 00427 int alpha, beta, betaY, betaC; 00428 int q; 00429 int mbtype[4]; 00430 00434 int mb_strong[4]; 00435 int clip[4]; 00436 00442 int cbp[4]; 00447 int uvcbp[4][2]; 00453 int mvmasks[4]; 00454 00455 mb_pos = row * s->mb_stride; 00456 for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ 00457 int mbtype = s->current_picture_ptr->mb_type[mb_pos]; 00458 if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype)) 00459 r->cbp_luma [mb_pos] = r->deblock_coefs[mb_pos] = 0xFFFF; 00460 if(IS_INTRA(mbtype)) 00461 r->cbp_chroma[mb_pos] = 0xFF; 00462 } 00463 mb_pos = row * s->mb_stride; 00464 for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ 00465 int y_h_deblock, y_v_deblock; 00466 int c_v_deblock[2], c_h_deblock[2]; 00467 int clip_left; 00468 int avail[4]; 00469 int y_to_deblock, c_to_deblock[2]; 00470 00471 q = s->current_picture_ptr->qscale_table[mb_pos]; 00472 alpha = rv40_alpha_tab[q]; 00473 beta = rv40_beta_tab [q]; 00474 betaY = betaC = beta * 3; 00475 if(s->width * s->height <= 176*144) 00476 betaY += beta; 00477 00478 avail[0] = 1; 00479 avail[1] = row; 00480 avail[2] = mb_x; 00481 avail[3] = row < s->mb_height - 1; 00482 for(i = 0; i < 4; i++){ 00483 if(avail[i]){ 00484 int pos = mb_pos + neighbour_offs_x[i] + neighbour_offs_y[i]*s->mb_stride; 00485 mvmasks[i] = r->deblock_coefs[pos]; 00486 mbtype [i] = s->current_picture_ptr->mb_type[pos]; 00487 cbp [i] = r->cbp_luma[pos]; 00488 uvcbp[i][0] = r->cbp_chroma[pos] & 0xF; 00489 uvcbp[i][1] = r->cbp_chroma[pos] >> 4; 00490 }else{ 00491 mvmasks[i] = 0; 00492 mbtype [i] = mbtype[0]; 00493 cbp [i] = 0; 00494 uvcbp[i][0] = uvcbp[i][1] = 0; 00495 } 00496 mb_strong[i] = IS_INTRA(mbtype[i]) || IS_SEPARATE_DC(mbtype[i]); 00497 clip[i] = rv40_filter_clip_tbl[mb_strong[i] + 1][q]; 00498 } 00499 y_to_deblock = mvmasks[POS_CUR] 00500 | (mvmasks[POS_BOTTOM] << 16); 00501 /* This pattern contains bits signalling that horizontal edges of 00502 * the current block can be filtered. 00503 * That happens when either of adjacent subblocks is coded or lies on 00504 * the edge of 8x8 blocks with motion vectors differing by more than 00505 * 3/4 pel in any component (any edge orientation for some reason). 00506 */ 00507 y_h_deblock = y_to_deblock 00508 | ((cbp[POS_CUR] << 4) & ~MASK_Y_TOP_ROW) 00509 | ((cbp[POS_TOP] & MASK_Y_LAST_ROW) >> 12); 00510 /* This pattern contains bits signalling that vertical edges of 00511 * the current block can be filtered. 00512 * That happens when either of adjacent subblocks is coded or lies on 00513 * the edge of 8x8 blocks with motion vectors differing by more than 00514 * 3/4 pel in any component (any edge orientation for some reason). 00515 */ 00516 y_v_deblock = y_to_deblock 00517 | ((cbp[POS_CUR] << 1) & ~MASK_Y_LEFT_COL) 00518 | ((cbp[POS_LEFT] & MASK_Y_RIGHT_COL) >> 3); 00519 if(!mb_x) 00520 y_v_deblock &= ~MASK_Y_LEFT_COL; 00521 if(!row) 00522 y_h_deblock &= ~MASK_Y_TOP_ROW; 00523 if(row == s->mb_height - 1 || (mb_strong[POS_CUR] || mb_strong[POS_BOTTOM])) 00524 y_h_deblock &= ~(MASK_Y_TOP_ROW << 16); 00525 /* Calculating chroma patterns is similar and easier since there is 00526 * no motion vector pattern for them. 00527 */ 00528 for(i = 0; i < 2; i++){ 00529 c_to_deblock[i] = (uvcbp[POS_BOTTOM][i] << 4) | uvcbp[POS_CUR][i]; 00530 c_v_deblock[i] = c_to_deblock[i] 00531 | ((uvcbp[POS_CUR] [i] << 1) & ~MASK_C_LEFT_COL) 00532 | ((uvcbp[POS_LEFT][i] & MASK_C_RIGHT_COL) >> 1); 00533 c_h_deblock[i] = c_to_deblock[i] 00534 | ((uvcbp[POS_TOP][i] & MASK_C_LAST_ROW) >> 2) 00535 | (uvcbp[POS_CUR][i] << 2); 00536 if(!mb_x) 00537 c_v_deblock[i] &= ~MASK_C_LEFT_COL; 00538 if(!row) 00539 c_h_deblock[i] &= ~MASK_C_TOP_ROW; 00540 if(row == s->mb_height - 1 || mb_strong[POS_CUR] || mb_strong[POS_BOTTOM]) 00541 c_h_deblock[i] &= ~(MASK_C_TOP_ROW << 4); 00542 } 00543 00544 for(j = 0; j < 16; j += 4){ 00545 Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize; 00546 for(i = 0; i < 4; i++, Y += 4){ 00547 int ij = i + j; 00548 int clip_cur = y_to_deblock & (MASK_CUR << ij) ? clip[POS_CUR] : 0; 00549 int dither = j ? ij : i*4; 00550 00551 // if bottom block is coded then we can filter its top edge 00552 // (or bottom edge of this block, which is the same) 00553 if(y_h_deblock & (MASK_BOTTOM << ij)){ 00554 rv40_h_loop_filter(Y+4*s->linesize, s->linesize, dither, 00555 y_to_deblock & (MASK_BOTTOM << ij) ? clip[POS_CUR] : 0, 00556 clip_cur, 00557 alpha, beta, betaY, 0, 0); 00558 } 00559 // filter left block edge in ordinary mode (with low filtering strength) 00560 if(y_v_deblock & (MASK_CUR << ij) && (i || !(mb_strong[POS_CUR] || mb_strong[POS_LEFT]))){ 00561 if(!i) 00562 clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0; 00563 else 00564 clip_left = y_to_deblock & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0; 00565 rv40_v_loop_filter(Y, s->linesize, dither, 00566 clip_cur, 00567 clip_left, 00568 alpha, beta, betaY, 0, 0); 00569 } 00570 // filter top edge of the current macroblock when filtering strength is high 00571 if(!j && y_h_deblock & (MASK_CUR << i) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){ 00572 rv40_h_loop_filter(Y, s->linesize, dither, 00573 clip_cur, 00574 mvmasks[POS_TOP] & (MASK_TOP << i) ? clip[POS_TOP] : 0, 00575 alpha, beta, betaY, 0, 1); 00576 } 00577 // filter left block edge in edge mode (with high filtering strength) 00578 if(y_v_deblock & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){ 00579 clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0; 00580 rv40_v_loop_filter(Y, s->linesize, dither, 00581 clip_cur, 00582 clip_left, 00583 alpha, beta, betaY, 0, 1); 00584 } 00585 } 00586 } 00587 for(k = 0; k < 2; k++){ 00588 for(j = 0; j < 2; j++){ 00589 C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j*4) * s->uvlinesize; 00590 for(i = 0; i < 2; i++, C += 4){ 00591 int ij = i + j*2; 00592 int clip_cur = c_to_deblock[k] & (MASK_CUR << ij) ? clip[POS_CUR] : 0; 00593 if(c_h_deblock[k] & (MASK_CUR << (ij+2))){ 00594 int clip_bot = c_to_deblock[k] & (MASK_CUR << (ij+2)) ? clip[POS_CUR] : 0; 00595 rv40_h_loop_filter(C+4*s->uvlinesize, s->uvlinesize, i*8, 00596 clip_bot, 00597 clip_cur, 00598 alpha, beta, betaC, 1, 0); 00599 } 00600 if((c_v_deblock[k] & (MASK_CUR << ij)) && (i || !(mb_strong[POS_CUR] || mb_strong[POS_LEFT]))){ 00601 if(!i) 00602 clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0; 00603 else 00604 clip_left = c_to_deblock[k] & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0; 00605 rv40_v_loop_filter(C, s->uvlinesize, j*8, 00606 clip_cur, 00607 clip_left, 00608 alpha, beta, betaC, 1, 0); 00609 } 00610 if(!j && c_h_deblock[k] & (MASK_CUR << ij) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){ 00611 int clip_top = uvcbp[POS_TOP][k] & (MASK_CUR << (ij+2)) ? clip[POS_TOP] : 0; 00612 rv40_h_loop_filter(C, s->uvlinesize, i*8, 00613 clip_cur, 00614 clip_top, 00615 alpha, beta, betaC, 1, 1); 00616 } 00617 if(c_v_deblock[k] & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){ 00618 clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0; 00619 rv40_v_loop_filter(C, s->uvlinesize, j*8, 00620 clip_cur, 00621 clip_left, 00622 alpha, beta, betaC, 1, 1); 00623 } 00624 } 00625 } 00626 } 00627 } 00628 } 00629 00633 static av_cold int rv40_decode_init(AVCodecContext *avctx) 00634 { 00635 RV34DecContext *r = avctx->priv_data; 00636 00637 r->rv30 = 0; 00638 ff_rv34_decode_init(avctx); 00639 if(!aic_top_vlc.bits) 00640 rv40_init_tables(); 00641 r->parse_slice_header = rv40_parse_slice_header; 00642 r->decode_intra_types = rv40_decode_intra_types; 00643 r->decode_mb_info = rv40_decode_mb_info; 00644 r->loop_filter = rv40_loop_filter; 00645 r->luma_dc_quant_i = rv40_luma_dc_quant[0]; 00646 r->luma_dc_quant_p = rv40_luma_dc_quant[1]; 00647 return 0; 00648 } 00649 00650 AVCodec rv40_decoder = { 00651 "rv40", 00652 CODEC_TYPE_VIDEO, 00653 CODEC_ID_RV40, 00654 sizeof(RV34DecContext), 00655 rv40_decode_init, 00656 NULL, 00657 ff_rv34_decode_end, 00658 ff_rv34_decode_frame, 00659 CODEC_CAP_DR1 | CODEC_CAP_DELAY, 00660 .flush = ff_mpeg_flush, 00661 .long_name = NULL_IF_CONFIG_SMALL("RealVideo 4.0"), 00662 .pix_fmts= ff_pixfmt_list_420, 00663 };