@ -274,148 +274,6 @@ static int rv40_decode_mb_info(RV34DecContext *r)
return 0 ;
}
# define CLIP_SYMM(a, b) av_clip(a, -(b), b)
/**
* weaker deblocking very similar to the one described in 4.4 .2 of JVT - A003r1
*/
static inline void rv40_weak_loop_filter ( uint8_t * src , const int step ,
const int filter_p1 , const int filter_q1 ,
const int alpha , const int beta ,
const int lim_p0q0 ,
const int lim_q1 , const int lim_p1 ,
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_p1 & & filter_q1 ) )
return ;
t < < = 2 ;
if ( filter_p1 & & filter_q1 )
t + = src [ - 2 * step ] - src [ 1 * step ] ;
diff = CLIP_SYMM ( ( t + 4 ) > > 3 , lim_p0q0 ) ;
src [ - 1 * step ] = cm [ src [ - 1 * step ] + diff ] ;
src [ 0 * step ] = cm [ src [ 0 * step ] - diff ] ;
if ( FFABS ( diff_p1p2 ) < = beta & & filter_p1 ) {
t = ( diff_p1p0 + diff_p1p2 - diff ) > > 1 ;
src [ - 2 * step ] = cm [ src [ - 2 * step ] - CLIP_SYMM ( t , lim_p1 ) ] ;
}
if ( FFABS ( diff_q1q2 ) < = beta & & filter_q1 ) {
t = ( diff_q1q0 + diff_q1q2 + diff ) > > 1 ;
src [ 1 * step ] = cm [ src [ 1 * step ] - CLIP_SYMM ( t , lim_q1 ) ] ;
}
}
static av_always_inline void rv40_adaptive_loop_filter ( uint8_t * src , const int step ,
const int stride , const int dmode ,
const int lim_q1 , const int lim_p1 ,
const int alpha ,
const int beta , const int beta2 ,
const int chroma , const int edge )
{
int diff_p1p0 [ 4 ] , diff_q1q0 [ 4 ] , diff_p1p2 [ 4 ] , diff_q1q2 [ 4 ] ;
int sum_p1p0 = 0 , sum_q1q0 = 0 , sum_p1p2 = 0 , sum_q1q2 = 0 ;
uint8_t * ptr ;
int flag_strong0 = 1 , flag_strong1 = 1 ;
int filter_p1 , filter_q1 ;
int i ;
int lims ;
for ( i = 0 , ptr = src ; i < 4 ; i + + , ptr + = stride ) {
diff_p1p0 [ i ] = ptr [ - 2 * step ] - ptr [ - 1 * step ] ;
diff_q1q0 [ i ] = ptr [ 1 * step ] - ptr [ 0 * step ] ;
sum_p1p0 + = diff_p1p0 [ i ] ;
sum_q1q0 + = diff_q1q0 [ i ] ;
}
filter_p1 = FFABS ( sum_p1p0 ) < ( beta < < 2 ) ;
filter_q1 = FFABS ( sum_q1q0 ) < ( beta < < 2 ) ;
if ( ! filter_p1 & & ! filter_q1 )
return ;
for ( i = 0 , ptr = src ; i < 4 ; i + + , ptr + = stride ) {
diff_p1p2 [ i ] = ptr [ - 2 * step ] - ptr [ - 3 * step ] ;
diff_q1q2 [ i ] = ptr [ 1 * step ] - ptr [ 2 * step ] ;
sum_p1p2 + = diff_p1p2 [ i ] ;
sum_q1q2 + = diff_q1q2 [ i ] ;
}
if ( edge ) {
flag_strong0 = filter_p1 & & ( FFABS ( sum_p1p2 ) < beta2 ) ;
flag_strong1 = filter_q1 & & ( FFABS ( sum_q1q2 ) < beta2 ) ;
} else {
flag_strong0 = flag_strong1 = 0 ;
}
lims = filter_p1 + filter_q1 + ( ( lim_q1 + lim_p1 ) > > 1 ) + 1 ;
if ( flag_strong0 & & flag_strong1 ) { /* strong filtering */
for ( i = 0 ; i < 4 ; i + + , src + = stride ) {
int sflag , p0 , q0 , p1 , q1 ;
int t = src [ 0 * step ] - src [ - 1 * step ] ;
if ( ! t ) continue ;
sflag = ( alpha * FFABS ( t ) ) > > 7 ;
if ( sflag > 1 ) continue ;
p0 = ( 25 * src [ - 3 * step ] + 26 * src [ - 2 * step ]
+ 26 * src [ - 1 * step ]
+ 26 * src [ 0 * step ] + 25 * src [ 1 * step ] + rv40_dither_l [ dmode + i ] ) > > 7 ;
q0 = ( 25 * src [ - 2 * step ] + 26 * src [ - 1 * step ]
+ 26 * src [ 0 * step ]
+ 26 * src [ 1 * step ] + 25 * src [ 2 * step ] + rv40_dither_r [ dmode + i ] ) > > 7 ;
if ( sflag ) {
p0 = av_clip ( p0 , src [ - 1 * step ] - lims , src [ - 1 * step ] + lims ) ;
q0 = av_clip ( q0 , src [ 0 * step ] - lims , src [ 0 * step ] + lims ) ;
}
p1 = ( 25 * src [ - 4 * step ] + 26 * src [ - 3 * step ]
+ 26 * src [ - 2 * step ]
+ 26 * p0 + 25 * src [ 0 * step ] + rv40_dither_l [ dmode + i ] ) > > 7 ;
q1 = ( 25 * src [ - 1 * step ] + 26 * q0
+ 26 * src [ 1 * step ]
+ 26 * src [ 2 * step ] + 25 * src [ 3 * step ] + rv40_dither_r [ dmode + i ] ) > > 7 ;
if ( sflag ) {
p1 = av_clip ( p1 , src [ - 2 * step ] - lims , src [ - 2 * step ] + lims ) ;
q1 = av_clip ( q1 , src [ 1 * step ] - lims , src [ 1 * step ] + lims ) ;
}
src [ - 2 * step ] = p1 ;
src [ - 1 * step ] = p0 ;
src [ 0 * step ] = q0 ;
src [ 1 * step ] = q1 ;
if ( ! chroma ) {
src [ - 3 * step ] = ( 25 * src [ - 1 * step ] + 26 * src [ - 2 * step ] + 51 * src [ - 3 * step ] + 26 * src [ - 4 * step ] + 64 ) > > 7 ;
src [ 2 * step ] = ( 25 * src [ 0 * step ] + 26 * src [ 1 * step ] + 51 * src [ 2 * step ] + 26 * src [ 3 * step ] + 64 ) > > 7 ;
}
}
} else if ( filter_p1 & & filter_q1 ) {
for ( i = 0 ; i < 4 ; i + + , src + = stride )
rv40_weak_loop_filter ( src , step , 1 , 1 , alpha , beta , lims , lim_q1 , lim_p1 ,
diff_p1p0 [ i ] , diff_q1q0 [ i ] , diff_p1p2 [ i ] , diff_q1q2 [ i ] ) ;
} else {
for ( i = 0 ; i < 4 ; i + + , src + = stride )
rv40_weak_loop_filter ( src , step , filter_p1 , filter_q1 ,
alpha , beta , lims > > 1 , lim_q1 > > 1 , lim_p1 > > 1 ,
diff_p1p0 [ i ] , diff_q1q0 [ i ] , diff_p1p2 [ i ] , diff_q1q2 [ i ] ) ;
}
}
static void rv40_v_loop_filter ( uint8_t * src , int stride , int dmode ,
int lim_q1 , int lim_p1 ,
int alpha , int beta , int beta2 , int chroma , int edge ) {
rv40_adaptive_loop_filter ( src , 1 , stride , dmode , lim_q1 , lim_p1 ,
alpha , beta , beta2 , chroma , edge ) ;
}
static void rv40_h_loop_filter ( uint8_t * src , int stride , int dmode ,
int lim_q1 , int lim_p1 ,
int alpha , int beta , int beta2 , int chroma , int edge ) {
rv40_adaptive_loop_filter ( src , stride , 1 , dmode , lim_q1 , lim_p1 ,
alpha , beta , beta2 , chroma , edge ) ;
}
enum RV40BlockPos {
POS_CUR ,
POS_TOP ,
@ -575,7 +433,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
// if bottom block is coded then we can filter its top edge
// (or bottom edge of this block, which is the same)
if ( y_h_deblock & ( MASK_BOTTOM < < ij ) ) {
rv40_h_loop_filter ( Y + 4 * s - > linesize , s - > linesize , dither ,
r - > rdsp . r v40_h_loop_filter( Y + 4 * s - > linesize , s - > linesize , dither ,
y_to_deblock & ( MASK_BOTTOM < < ij ) ? clip [ POS_CUR ] : 0 ,
clip_cur ,
alpha , beta , betaY , 0 , 0 ) ;
@ -586,14 +444,14 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
clip_left = mvmasks [ POS_LEFT ] & ( MASK_RIGHT < < j ) ? clip [ POS_LEFT ] : 0 ;
else
clip_left = y_to_deblock & ( MASK_CUR < < ( ij - 1 ) ) ? clip [ POS_CUR ] : 0 ;
rv40_v_loop_filter ( Y , s - > linesize , dither ,
r - > rdsp . r v40_v_loop_filter( Y , s - > linesize , dither ,
clip_cur ,
clip_left ,
alpha , beta , betaY , 0 , 0 ) ;
}
// filter top edge of the current macroblock when filtering strength is high
if ( ! j & & y_h_deblock & ( MASK_CUR < < i ) & & ( mb_strong [ POS_CUR ] | | mb_strong [ POS_TOP ] ) ) {
rv40_h_loop_filter ( Y , s - > linesize , dither ,
r - > rdsp . r v40_h_loop_filter( Y , s - > linesize , dither ,
clip_cur ,
mvmasks [ POS_TOP ] & ( MASK_TOP < < i ) ? clip [ POS_TOP ] : 0 ,
alpha , beta , betaY , 0 , 1 ) ;
@ -601,7 +459,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
// filter left block edge in edge mode (with high filtering strength)
if ( y_v_deblock & ( MASK_CUR < < ij ) & & ! i & & ( mb_strong [ POS_CUR ] | | mb_strong [ POS_LEFT ] ) ) {
clip_left = mvmasks [ POS_LEFT ] & ( MASK_RIGHT < < j ) ? clip [ POS_LEFT ] : 0 ;
rv40_v_loop_filter ( Y , s - > linesize , dither ,
r - > rdsp . r v40_v_loop_filter( Y , s - > linesize , dither ,
clip_cur ,
clip_left ,
alpha , beta , betaY , 0 , 1 ) ;
@ -616,7 +474,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
int clip_cur = c_to_deblock [ k ] & ( MASK_CUR < < ij ) ? clip [ POS_CUR ] : 0 ;
if ( c_h_deblock [ k ] & ( MASK_CUR < < ( ij + 2 ) ) ) {
int clip_bot = c_to_deblock [ k ] & ( MASK_CUR < < ( ij + 2 ) ) ? clip [ POS_CUR ] : 0 ;
rv40_h_loop_filter ( C + 4 * s - > uvlinesize , s - > uvlinesize , i * 8 ,
r - > rdsp . r v40_h_loop_filter( C + 4 * s - > uvlinesize , s - > uvlinesize , i * 8 ,
clip_bot ,
clip_cur ,
alpha , beta , betaC , 1 , 0 ) ;
@ -626,21 +484,21 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
clip_left = uvcbp [ POS_LEFT ] [ k ] & ( MASK_CUR < < ( 2 * j + 1 ) ) ? clip [ POS_LEFT ] : 0 ;
else
clip_left = c_to_deblock [ k ] & ( MASK_CUR < < ( ij - 1 ) ) ? clip [ POS_CUR ] : 0 ;
rv40_v_loop_filter ( C , s - > uvlinesize , j * 8 ,
r - > rdsp . r v40_v_loop_filter( C , s - > uvlinesize , j * 8 ,
clip_cur ,
clip_left ,
alpha , beta , betaC , 1 , 0 ) ;
}
if ( ! j & & c_h_deblock [ k ] & ( MASK_CUR < < ij ) & & ( mb_strong [ POS_CUR ] | | mb_strong [ POS_TOP ] ) ) {
int clip_top = uvcbp [ POS_TOP ] [ k ] & ( MASK_CUR < < ( ij + 2 ) ) ? clip [ POS_TOP ] : 0 ;
rv40_h_loop_filter ( C , s - > uvlinesize , i * 8 ,
r - > rdsp . r v40_h_loop_filter( C , s - > uvlinesize , i * 8 ,
clip_cur ,
clip_top ,
alpha , beta , betaC , 1 , 1 ) ;
}
if ( c_v_deblock [ k ] & ( MASK_CUR < < ij ) & & ! i & & ( mb_strong [ POS_CUR ] | | mb_strong [ POS_LEFT ] ) ) {
clip_left = uvcbp [ POS_LEFT ] [ k ] & ( MASK_CUR < < ( 2 * j + 1 ) ) ? clip [ POS_LEFT ] : 0 ;
rv40_v_loop_filter ( C , s - > uvlinesize , j * 8 ,
r - > rdsp . r v40_v_loop_filter( C , s - > uvlinesize , j * 8 ,
clip_cur ,
clip_left ,
alpha , beta , betaC , 1 , 1 ) ;