[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