[FFmpeg-devel] [PATCH i/N] RV30 loop filter

Kostya kostya.shishkov
Sat Feb 23 11:57:29 CET 2008


$subj

Probably correct.
-------------- next part --------------
Index: libavcodec/rv30data.h
===================================================================
--- libavcodec/rv30data.h	(revision 12129)
+++ libavcodec/rv30data.h	(working copy)
@@ -171,4 +171,17 @@
     2, 7, 8, 4, 0, 6, 1, 5, 3,
     2, 8, 3, 0, 7, 4, 1, 6, 5,
 };
+
+/**
+ * Loop filter limits are taken from this table.
+ */
+static const uint8_t rv30_loop_filt_lim[7][32] = {
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9 }
+};
 #endif /* FFMPEG_RV30DATA_H */
Index: libavcodec/rv30.c
===================================================================
--- libavcodec/rv30.c	(revision 12129)
+++ libavcodec/rv30.c	(working copy)
@@ -111,6 +111,103 @@
         return rv30_b_types[code];
 }
 
+static inline void rv30_weak_loop_filter(uint8_t *src, const int step,
+                                         const int stride, const int lim)
+{
+    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    int i, diff;
+
+    if(!lim) return;
+    for(i = 0; i < 4; i++){
+        diff = ((src[-2*step] - src[1*step]) - (src[-1*step] - src[0*step])*4) >> 3;
+        diff = av_clip(diff, -lim, lim);
+        src[-1*step] = cm[src[-1*step] + diff];
+        src[ 0*step] = cm[src[ 0*step] - diff];
+        src += stride;
+    }
+}
+
+static void rv30_loop_filter(RV34DecContext *r)
+{
+    MpegEncContext *s = &r->s;
+    int mb_pos;
+    int i, j;
+    int strength = 0;//FIXME how to determine correct value?
+    const uint8_t* lim = rv30_loop_filt_lim[strength];
+    int cbp1, cbp2, q;
+
+    s->mb_x = 0;
+    for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++){
+        ff_init_block_index(s);
+        mb_pos = s->mb_y * s->mb_stride;
+        for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++, mb_pos++){
+            ff_update_block_index(s);
+            if(!IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])) continue;
+            if(s->mb_x && IS_INTRA(s->current_picture_ptr->mb_type[mb_pos - 1])){
+                cbp1 = r->cbp_luma[mb_pos - 1];
+                cbp2 = r->cbp_luma[mb_pos];
+                q = s->current_picture_ptr->qscale_table[mb_pos - 1];
+                for(i = 0; i < 16; i += 4, cbp1 >>= 4, cbp2 >>= 4)
+                    if((cbp1 & 8) && (cbp2 & 1))
+                        rv30_weak_loop_filter(s->dest[0] + i * s->linesize, 1, s->linesize, lim[q]);
+                cbp1 = r->cbp_chroma[mb_pos - 1];
+                cbp2 = r->cbp_chroma[mb_pos];
+                for(i = 0; i < 8; i += 4, cbp1 >>= 2, cbp2 >>= 2){
+                    if((cbp1 & 0x02) && (cbp2 & 0x01))
+                        rv30_weak_loop_filter(s->dest[1] + i * s->uvlinesize, 1, s->uvlinesize, lim[q]);
+                    if((cbp1 & 0x20) && (cbp2 & 0x10))
+                        rv30_weak_loop_filter(s->dest[2] + i * s->uvlinesize, 1, s->uvlinesize, lim[q]);
+                }
+            }
+            q = s->current_picture_ptr->qscale_table[mb_pos];
+            for(j = 4; j < 16; j += 4){
+                cbp1 = r->cbp_luma[mb_pos] >> ((j >> 2) - 1);
+                for(i = 0; i < 16; i += 4, cbp1 >>= 4)
+                    if(cbp1 & 3)
+                        rv30_weak_loop_filter(s->dest[0] + j + i * s->linesize, 1, s->linesize, lim[q]);
+            }
+            cbp1 = r->cbp_chroma[mb_pos];
+            for(i = 0; i < 8; i += 4, cbp1 >>= 2){
+                if(cbp1 & 0x03)
+                    rv30_weak_loop_filter(s->dest[1] + 4 + i * s->uvlinesize, 1, s->uvlinesize, lim[q]);
+                if(cbp1 & 0x30)
+                    rv30_weak_loop_filter(s->dest[2] + 4 + i * s->uvlinesize, 1, s->uvlinesize, lim[q]);
+            }
+
+            if(s->mb_y && IS_INTRA(s->current_picture_ptr->mb_type[mb_pos - s->mb_stride])){
+                cbp1 = r->cbp_luma[mb_pos - s->mb_stride] >> 12;
+                cbp2 = r->cbp_luma[mb_pos];
+                q = s->current_picture_ptr->qscale_table[mb_pos - s->mb_stride];
+                for(i = 0; i < 16; i += 4, cbp1 >>= 1, cbp2 >>= 1)
+                    if((cbp1 & 1) && (cbp2 & 1))
+                        rv30_weak_loop_filter(s->dest[0] + i, s->linesize, 1, lim[q]);
+                cbp1 = r->cbp_chroma[mb_pos - s->mb_stride];
+                cbp2 = r->cbp_chroma[mb_pos];
+                for(i = 0; i < 8; i += 4, cbp1 >>= 1, cbp2 >>= 1){
+                    if((cbp1 & 0x04) && (cbp2 & 0x01))
+                        rv30_weak_loop_filter(s->dest[1] + i * s->uvlinesize, s->uvlinesize, 1, lim[q]);
+                    if((cbp1 & 0x40) && (cbp2 & 0x10))
+                        rv30_weak_loop_filter(s->dest[2] + i * s->uvlinesize, s->uvlinesize, 1, lim[q]);
+                }
+            }
+            q = s->current_picture_ptr->qscale_table[mb_pos];
+            for(j = 4; j < 16; j += 4){
+                cbp1 = r->cbp_luma[mb_pos] >> (j - 4);
+                for(i = 0; i < 16; i += 4, cbp1 >>= 4)
+                    if(cbp1 & 0x11)
+                        rv30_weak_loop_filter(s->dest[0] + i + j * s->linesize, s->linesize, 1, lim[q]);
+            }
+            cbp1 = r->cbp_chroma[mb_pos];
+            for(i = 0; i < 8; i += 4, cbp1 >>= 2){
+                if(cbp1 & 0x05)
+                    rv30_weak_loop_filter(s->dest[1] + i + 4 * s->uvlinesize, s->uvlinesize, 1, lim[q]);
+                if(cbp1 & 0x50)
+                    rv30_weak_loop_filter(s->dest[2] + i + 4 * s->uvlinesize, s->uvlinesize, 1, lim[q]);
+            }
+        }
+    }
+}
+
 /**
  * Initialize decoder.
  */
@@ -129,6 +226,7 @@
     r->parse_slice_header = rv30_parse_slice_header;
     r->decode_intra_types = rv30_decode_intra_types;
     r->decode_mb_info     = rv30_decode_mb_info;
+    r->loop_filter        = rv30_loop_filter;
     r->luma_dc_quant_i = rv30_luma_dc_quant;
     r->luma_dc_quant_p = rv30_luma_dc_quant;
     return 0;



More information about the ffmpeg-devel mailing list