[FFmpeg-devel] [PATCH] RV40 Loop Filter (again)
Michael Niedermayer
michaelni
Wed Nov 12 19:46:32 CET 2008
On Wed, Nov 12, 2008 at 09:05:11AM +0200, Kostya wrote:
> $subj
[...]
> /**
> + * weaker deblocking very similar to the one described in 4.4.2 of JVT-A003r1
> + *
> + * @param filter_outer flag signalling that pixels at distance 2 from the edge
> + * should be filtered
> + * @param filter_inner flag signalling that pixels at distance 1 from the edge
> + * should be filtered (pixels at the edge are always filtered)
> + */
> +static inline void rv40_weak_loop_filter(uint8_t *src, const int step,
> + const int filter_outer, const int filter_inner,
> + const int alpha, const int beta,
> + const int lim0, const int lim1, const int lim2,
> + const int diff_p1p0, const int diff_q1q0,
> + const int diff_p1p2, const int diff_q1q2)
> +{
> + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
> + int t, u, diff;
> +
> + t = src[0*step] - src[-1*step];
> + if(!t)
> + return;
> + u = (alpha * FFABS(t)) >> 7;
> + if(u > 3 - (filter_inner && filter_outer))
> + return;
> +
> + t <<= 2;
> + if(filter_inner && filter_outer)
> + t += src[-2*step] - src[1*step];
> + diff = CLIP_SYMM((t + 4) >> 3, lim0);
> + src[-1*step] = cm[src[-1*step] + diff];
> + src[ 0*step] = cm[src[ 0*step] - diff];
> + if(FFABS(diff_p1p2) <= beta && filter_outer){
> + t = (diff_p1p0 + diff_p1p2 - diff) >> 1;
> + src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim2)];
> + }
> + if(FFABS(diff_q1q2) <= beta && filter_inner){
> + t = (diff_q1q0 + diff_q1q2 + diff) >> 1;
> + src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim1)];
> + }
> +}
let me say it the third time, it is left and right not inner and outer.
[outer left] [inner left] | [inner right] [outer right]
^
edge
> +
> +/**
> + * RV4 strong edge filter with coefficients (25 26 26 26 25)
> + */
> +#define RV40_STRONG_FILTER(src, step, start, bias) \
> + (25*src[(start-2)*step] + 26*src[(start-1)*step] + 26*src[start*step] + \
> + 26*src[(start+1)*step] + 25*src[(start+2)*step] + bias) >> 7
> +
> +/**
> + * RV4 strong edge filter for outermost pixels with coefficients effectively
> + * (25 26 51 26) because of mirroring - for the case when edge to be filtered
> + * lies to the left (or bottom) of the filtered pixel
> + */
> +#define RV40_STRONG_FILTER_LEFT(src, step) \
> + (25*src[-1*step] + 26*src[-2*step] + 51*src[-3*step] + 26*src[-4*step] + 64) >> 7
> +
> +/**
> + * RV4 strong edge filter for outermost pixels with coefficients effectively
> + * (25 26 51 26) because of mirroring - for the case when edge to be filtered
> + * lies to the right (or top) of the filtered pixel
> + */
> +#define RV40_STRONG_FILTER_RIGHT(src, step) \
> + (25*src[0*step] + 26*src[1*step] + 51*src[2*step] + 26*src[3*step] + 64) >> 7
these macros are very nice and clean, i do like them, but they are each
just used once, iam not sure if it would not be simpler to just write the
code there without macros.
[...]
> + for(i = 1; i < 4; i++){
> + mvmasks[i] = 0;
> + mbtype [i] = mbtype[0];
> + cbp [i] = 0;
> + uvcbp[1][0] = uvcbp[1][1] = 0;
> + }
> + if(s->mb_y){
> + mvmasks[POS_TOP] = r->deblock_coefs[mb_pos - s->mb_stride] & MASK_Y_LAST_ROW;
> + mbtype [POS_TOP] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
> + cbp [POS_TOP] = r->cbp_luma[mb_pos - s->mb_stride] & MASK_Y_LAST_ROW;
> + uvcbp[POS_TOP][0] = r->cbp_chroma[mb_pos - s->mb_stride] & MASK_C_LAST_ROW;
> + uvcbp[POS_TOP][1] = (r->cbp_chroma[mb_pos - s->mb_stride] >> 4) & MASK_C_LAST_ROW;
> + }
> + if(s->mb_x){
> + mvmasks[POS_LEFT] = r->deblock_coefs[mb_pos - 1] & MASK_Y_RIGHT_COL;
> + mbtype [POS_LEFT] = s->current_picture_ptr->mb_type[mb_pos - 1];
> + cbp [POS_LEFT] = r->cbp_luma[mb_pos - 1] & MASK_Y_RIGHT_COL;
> + uvcbp[POS_LEFT][0] = r->cbp_chroma[mb_pos - 1] & MASK_C_RIGHT_COL;
> + uvcbp[POS_LEFT][1] = (r->cbp_chroma[mb_pos - 1] >> 4) & MASK_C_RIGHT_COL;
> + }
> + if(s->mb_y < s->mb_height - 1){
> + mvmasks[POS_BOTTOM] = r->deblock_coefs[mb_pos + s->mb_stride] & MASK_Y_TOP_ROW;
> + mbtype [POS_BOTTOM] = s->current_picture_ptr->mb_type[mb_pos + s->mb_stride];
> + cbp [POS_BOTTOM] = r->cbp_luma[mb_pos + s->mb_stride] & MASK_Y_TOP_ROW;
> + uvcbp[POS_BOTTOM][0] = r->cbp_chroma[mb_pos + s->mb_stride] & MASK_C_TOP_ROW;
> + uvcbp[POS_BOTTOM][1] = (r->cbp_chroma[mb_pos + s->mb_stride] >> 4) & MASK_C_TOP_ROW;
> + }
as said already, the & can be moved down
then this can then be factorized into a loop
> + for(i = 0; i < 4; i++){
> + strength[i] = (IS_INTRA(mbtype[i]) || IS_SEPARATE_DC(mbtype[i])) ? 2 : 1;
> + clip[i] = rv40_filter_clip_tbl[strength[i]][q];
> + }
> + /* This pattern contains bits signalling that horizontal edges of
> + * the current block can be filtered.
> + * That happens when either of adjacent subblocks is coded or lies on
> + * the edge of 8x8 blocks with motion vectors differing by more than
> + * 3/4 pel in any component.
> + */
> + y_h_deblock = cbp[POS_CUR] | (cbp[POS_BOTTOM] << 16)
> + | ((cbp[POS_CUR] << 4) & ~MASK_Y_TOP_ROW) | (cbp[POS_TOP] >> 12)
> + | mvmasks[POS_CUR] | (mvmasks[POS_BOTTOM] << 16);
[...]
> + | mvmasks[0];
see previous review, hint 0 vs enum
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Awnsering whenever a program halts or runs forever is
On a turing machine, in general impossible (turings halting problem).
On any real computer, always possible as a real computer has a finite number
of states N, and will either halt in less than N cycles or never halt.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20081112/9bcac805/attachment.pgp>
More information about the ffmpeg-devel
mailing list