# HG changeset patch # User conrad # Date 1239776422 0 # Node ID a91f609387633d84e9e499f33462a66dd7e4ddee # Parent e14cd3ac38063de0b90f92db6d5cbbd92a417b2e Move VC1 loop filter to DSPContext diff -r e14cd3ac3806 -r a91f60938763 dsputil.h --- a/dsputil.h Wed Apr 15 02:25:42 2009 +0000 +++ b/dsputil.h Wed Apr 15 06:20:22 2009 +0000 @@ -482,6 +482,7 @@ void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block); void (*vc1_v_overlap)(uint8_t* src, int stride); void (*vc1_h_overlap)(uint8_t* src, int stride); + void (*vc1_loop_filter)(uint8_t *src, int step, int stride, int len, int pq); /* put 8x8 block with bicubic interpolation and quarterpel precision * last argument is actually round value instead of height */ diff -r e14cd3ac3806 -r a91f60938763 vc1.c --- a/vc1.c Wed Apr 15 02:25:42 2009 +0000 +++ b/vc1.c Wed Apr 15 06:20:22 2009 +0000 @@ -310,87 +310,19 @@ /** @} */ //Bitplane group -/** - * VC-1 in-loop deblocking filter for one line - * @param src source block type - * @param stride block stride - * @param pq block quantizer - * @return whether other 3 pairs should be filtered or not - * @see 8.6 - */ -static av_always_inline int vc1_filter_line(uint8_t* src, int stride, int pq){ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - int a0 = (2*(src[-2*stride] - src[ 1*stride]) - 5*(src[-1*stride] - src[ 0*stride]) + 4) >> 3; - int a0_sign = a0 >> 31; /* Store sign */ - a0 = (a0 ^ a0_sign) - a0_sign; /* a0 = FFABS(a0); */ - if(a0 < pq){ - int a1 = FFABS((2*(src[-4*stride] - src[-1*stride]) - 5*(src[-3*stride] - src[-2*stride]) + 4) >> 3); - int a2 = FFABS((2*(src[ 0*stride] - src[ 3*stride]) - 5*(src[ 1*stride] - src[ 2*stride]) + 4) >> 3); - if(a1 < a0 || a2 < a0){ - int clip = src[-1*stride] - src[ 0*stride]; - int clip_sign = clip >> 31; - clip = ((clip ^ clip_sign) - clip_sign)>>1; - if(clip){ - int a3 = FFMIN(a1, a2); - int d = 5 * (a3 - a0); - int d_sign = (d >> 31); - d = ((d ^ d_sign) - d_sign) >> 3; - d_sign ^= a0_sign; - - if( d_sign ^ clip_sign ) - d = 0; - else{ - d = FFMIN(d, clip); - d = (d ^ d_sign) - d_sign; /* Restore sign */ - src[-1*stride] = cm[src[-1*stride] - d]; - src[ 0*stride] = cm[src[ 0*stride] + d]; - } - return 1; - } - } - } - return 0; -} - -/** - * VC-1 in-loop deblocking filter - * @param src source block type - * @param step distance between horizontally adjacent elements - * @param stride distance between vertically adjacent elements - * @param len edge length to filter (4 or 8 pixels) - * @param pq block quantizer - * @see 8.6 - */ -static void vc1_loop_filter(uint8_t* src, int step, int stride, int len, int pq) -{ - int i; - int filt3; - - for(i = 0; i < len; i += 4){ - filt3 = vc1_filter_line(src + 2*step, stride, pq); - if(filt3){ - vc1_filter_line(src + 0*step, stride, pq); - vc1_filter_line(src + 1*step, stride, pq); - vc1_filter_line(src + 3*step, stride, pq); - } - src += step * 4; - } -} - static void vc1_loop_filter_iblk(MpegEncContext *s, int pq) { int i, j; if(!s->first_slice_line) - vc1_loop_filter(s->dest[0], 1, s->linesize, 16, pq); - vc1_loop_filter(s->dest[0] + 8*s->linesize, 1, s->linesize, 16, pq); + s->dsp.vc1_loop_filter(s->dest[0], 1, s->linesize, 16, pq); + s->dsp.vc1_loop_filter(s->dest[0] + 8*s->linesize, 1, s->linesize, 16, pq); for(i = !s->mb_x*8; i < 16; i += 8) - vc1_loop_filter(s->dest[0] + i, s->linesize, 1, 16, pq); + s->dsp.vc1_loop_filter(s->dest[0] + i, s->linesize, 1, 16, pq); for(j = 0; j < 2; j++){ if(!s->first_slice_line) - vc1_loop_filter(s->dest[j+1], 1, s->uvlinesize, 8, pq); + s->dsp.vc1_loop_filter(s->dest[j+1], 1, s->uvlinesize, 8, pq); if(s->mb_x) - vc1_loop_filter(s->dest[j+1], s->uvlinesize, 1, 8, pq); + s->dsp.vc1_loop_filter(s->dest[j+1], s->uvlinesize, 1, 8, pq); } } @@ -3050,9 +2982,9 @@ s->dsp.vc1_inv_trans_8x8(block); s->dsp.add_pixels_clamped(block, dst, linesize); if(apply_filter && cbp_top & 0xC) - vc1_loop_filter(dst, 1, linesize, 8, mquant); + s->dsp.vc1_loop_filter(dst, 1, linesize, 8, mquant); if(apply_filter && cbp_left & 0xA) - vc1_loop_filter(dst, linesize, 1, 8, mquant); + s->dsp.vc1_loop_filter(dst, linesize, 1, 8, mquant); } break; case TT_4X4: @@ -3074,9 +3006,9 @@ if(!(subblkpat & (1 << (3 - j))) && !skip_block){ s->dsp.vc1_inv_trans_4x4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, block + off); if(apply_filter && (j&2 ? pat & (1<<(j-2)) : (cbp_top & (1 << (j + 2))))) - vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, 1, linesize, 4, mquant); + s->dsp.vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, 1, linesize, 4, mquant); if(apply_filter && (j&1 ? pat & (1<<(j-1)) : (cbp_left & (1 << (j + 1))))) - vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, linesize, 1, 4, mquant); + s->dsp.vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, linesize, 1, 4, mquant); } } break; @@ -3099,9 +3031,9 @@ if(!(subblkpat & (1 << (1 - j))) && !skip_block){ s->dsp.vc1_inv_trans_8x4(dst + j*4*linesize, linesize, block + off); if(apply_filter && j ? pat & 0x3 : (cbp_top & 0xC)) - vc1_loop_filter(dst + j*4*linesize, 1, linesize, 8, mquant); + s->dsp.vc1_loop_filter(dst + j*4*linesize, 1, linesize, 8, mquant); if(apply_filter && cbp_left & (2 << j)) - vc1_loop_filter(dst + j*4*linesize, linesize, 1, 4, mquant); + s->dsp.vc1_loop_filter(dst + j*4*linesize, linesize, 1, 4, mquant); } } break; @@ -3124,9 +3056,9 @@ if(!(subblkpat & (1 << (1 - j))) && !skip_block){ s->dsp.vc1_inv_trans_4x8(dst + j*4, linesize, block + off); if(apply_filter && cbp_top & (2 << j)) - vc1_loop_filter(dst + j*4, 1, linesize, 4, mquant); + s->dsp.vc1_loop_filter(dst + j*4, 1, linesize, 4, mquant); if(apply_filter && j ? pat & 0x5 : (cbp_left & 0xA)) - vc1_loop_filter(dst + j*4, linesize, 1, 8, mquant); + s->dsp.vc1_loop_filter(dst + j*4, linesize, 1, 8, mquant); } } break; @@ -3249,9 +3181,9 @@ top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); } if(left_cbp & 0xC) - vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); + s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); if(top_cbp & 0xA) - vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); + s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); } block_cbp |= 0xF << (i << 2); } else if(val) { @@ -3266,9 +3198,9 @@ top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); } if(left_cbp & 0xC) - vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); + s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); if(top_cbp & 0xA) - vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); + s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); } pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp); block_cbp |= pat << (i << 2); @@ -3380,9 +3312,9 @@ top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); } if(left_cbp & 0xC) - vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); + s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); if(top_cbp & 0xA) - vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); + s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); } block_cbp |= 0xF << (i << 2); } else if(is_coded[i]) { @@ -3397,9 +3329,9 @@ top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); } if(left_cbp & 0xC) - vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); + s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); if(top_cbp & 0xA) - vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); + s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); } pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp); block_cbp |= pat << (i << 2); diff -r e14cd3ac3806 -r a91f60938763 vc1dsp.c --- a/vc1dsp.c Wed Apr 15 02:25:42 2009 +0000 +++ b/vc1dsp.c Wed Apr 15 06:20:22 2009 +0000 @@ -78,6 +78,73 @@ } } +/** + * VC-1 in-loop deblocking filter for one line + * @param src source block type + * @param stride block stride + * @param pq block quantizer + * @return whether other 3 pairs should be filtered or not + * @see 8.6 + */ +static av_always_inline int vc1_filter_line(uint8_t* src, int stride, int pq){ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + + int a0 = (2*(src[-2*stride] - src[ 1*stride]) - 5*(src[-1*stride] - src[ 0*stride]) + 4) >> 3; + int a0_sign = a0 >> 31; /* Store sign */ + a0 = (a0 ^ a0_sign) - a0_sign; /* a0 = FFABS(a0); */ + if(a0 < pq){ + int a1 = FFABS((2*(src[-4*stride] - src[-1*stride]) - 5*(src[-3*stride] - src[-2*stride]) + 4) >> 3); + int a2 = FFABS((2*(src[ 0*stride] - src[ 3*stride]) - 5*(src[ 1*stride] - src[ 2*stride]) + 4) >> 3); + if(a1 < a0 || a2 < a0){ + int clip = src[-1*stride] - src[ 0*stride]; + int clip_sign = clip >> 31; + clip = ((clip ^ clip_sign) - clip_sign)>>1; + if(clip){ + int a3 = FFMIN(a1, a2); + int d = 5 * (a3 - a0); + int d_sign = (d >> 31); + d = ((d ^ d_sign) - d_sign) >> 3; + d_sign ^= a0_sign; + + if( d_sign ^ clip_sign ) + d = 0; + else{ + d = FFMIN(d, clip); + d = (d ^ d_sign) - d_sign; /* Restore sign */ + src[-1*stride] = cm[src[-1*stride] - d]; + src[ 0*stride] = cm[src[ 0*stride] + d]; + } + return 1; + } + } + } + return 0; +} + +/** + * VC-1 in-loop deblocking filter + * @param src source block type + * @param step distance between horizontally adjacent elements + * @param stride distance between vertically adjacent elements + * @param len edge length to filter (4 or 8 pixels) + * @param pq block quantizer + * @see 8.6 + */ +static void vc1_loop_filter(uint8_t* src, int step, int stride, int len, int pq) +{ + int i; + int filt3; + + for(i = 0; i < len; i += 4){ + filt3 = vc1_filter_line(src + 2*step, stride, pq); + if(filt3){ + vc1_filter_line(src + 0*step, stride, pq); + vc1_filter_line(src + 1*step, stride, pq); + vc1_filter_line(src + 3*step, stride, pq); + } + src += step * 4; + } +} /** Do inverse transform on 8x8 block */ @@ -450,6 +517,7 @@ dsp->vc1_inv_trans_4x4 = vc1_inv_trans_4x4_c; dsp->vc1_h_overlap = vc1_h_overlap_c; dsp->vc1_v_overlap = vc1_v_overlap_c; + dsp->vc1_loop_filter = vc1_loop_filter; dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_c; dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_c;