[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