@ -28,6 +28,11 @@
# include "h264pred.h"
# include "rectangle.h"
typedef struct {
uint8_t filter_level ;
uint8_t inner_limit ;
} VP8FilterStrength ;
typedef struct {
uint8_t segment ;
uint8_t skip ;
@ -79,6 +84,7 @@ typedef struct {
VP8Macroblock * macroblocks ;
VP8Macroblock * macroblocks_base ;
VP8FilterStrength * filter_strength ;
int mb_stride ;
uint8_t * intra4x4_pred_mode ;
@ -231,11 +237,12 @@ static int update_dimensions(VP8Context *s, int width, int height)
s - > b4_stride = 4 * s - > mb_stride ;
s - > macroblocks_base = av_mallocz ( s - > mb_stride * ( s - > mb_height + 1 ) * sizeof ( * s - > macroblocks ) ) ;
s - > filter_strength = av_mallocz ( s - > mb_stride * sizeof ( * s - > filter_strength ) ) ;
s - > intra4x4_pred_mode_base = av_mallocz ( s - > b4_stride * ( 4 * s - > mb_height + 1 ) ) ;
s - > top_nnz = av_mallocz ( s - > mb_width * sizeof ( * s - > top_nnz ) ) ;
s - > top_border = av_mallocz ( ( s - > mb_width + 1 ) * sizeof ( * s - > top_border ) ) ;
if ( ! s - > macroblocks_base | | ! s - > intra4x4_pred_mode_base | | ! s - > top_nnz | | ! s - > top_border )
if ( ! s - > macroblocks_base | | ! s - > filter_strength | | ! s - > intra4x4_pred_mode_base | | ! s - > top_nnz | | ! s - > top_border )
return AVERROR ( ENOMEM ) ;
s - > macroblocks = s - > macroblocks_base + 1 + s - > mb_stride ;
@ -1212,7 +1219,7 @@ static void idct_mb(VP8Context *s, uint8_t *y_dst, uint8_t *u_dst, uint8_t *v_ds
}
}
static void filter_level_for_mb ( VP8Context * s , VP8Macroblock * mb , int * level , int * inner , int * hev_thresh )
static void filter_level_for_mb ( VP8Context * s , VP8Macroblock * mb , VP8FilterStrength * f )
{
int interior_limit , filter_level ;
@ -1247,34 +1254,32 @@ static void filter_level_for_mb(VP8Context *s, VP8Macroblock *mb, int *level, in
}
interior_limit = FFMAX ( interior_limit , 1 ) ;
* level = filter_level ;
* inner = interior_limit ;
if ( hev_thresh ) {
* hev_thresh = filter_level > = 15 ;
if ( s - > keyframe ) {
if ( filter_level > = 40 )
* hev_thresh = 2 ;
} else {
if ( filter_level > = 40 )
* hev_thresh = 3 ;
else if ( filter_level > = 20 )
* hev_thresh = 2 ;
}
}
f - > filter_level = filter_level ;
f - > inner_limit = interior_limit ;
}
static void filter_mb ( VP8Context * s , uint8_t * dst [ 3 ] , VP8Macroblock * mb , int mb_x , int mb_y )
static void filter_mb ( VP8Context * s , uint8_t * dst [ 3 ] , VP8Macroblock * mb , VP8FilterStrength * f , int mb_x , int mb_y )
{
int filter_level , inner_limit , hev_thresh , mbedge_lim , bedge_lim ;
int mbedge_lim , bedge_lim , hev_thresh ;
int filter_level = f - > filter_level ;
int inner_limit = f - > inner_limit ;
filter_level_for_mb ( s , mb , & filter_level , & inner_limit , & hev_thresh ) ;
if ( ! filter_level )
return ;
mbedge_lim = 2 * ( filter_level + 2 ) + inner_limit ;
bedge_lim = 2 * filter_level + inner_limit ;
hev_thresh = filter_level > = 15 ;
if ( s - > keyframe ) {
if ( filter_level > = 40 )
hev_thresh = 2 ;
} else {
if ( filter_level > = 40 )
hev_thresh = 3 ;
else if ( filter_level > = 20 )
hev_thresh = 2 ;
}
if ( mb_x ) {
s - > vp8dsp . vp8_h_loop_filter16y ( dst [ 0 ] , s - > linesize ,
@ -1319,11 +1324,12 @@ static void filter_mb(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb, int mb_
}
}
static void filter_mb_simple ( VP8Context * s , uint8_t * dst , VP8Macroblock * mb , int mb_x , int mb_y )
static void filter_mb_simple ( VP8Context * s , uint8_t * dst , VP8Macroblock * mb , VP8FilterStrength * f , int mb_x , int mb_y )
{
int filter_level , inner_limit , mbedge_lim , bedge_lim ;
int mbedge_lim , bedge_lim ;
int filter_level = f - > filter_level ;
int inner_limit = f - > inner_limit ;
filter_level_for_mb ( s , mb , & filter_level , & inner_limit , NULL ) ;
if ( ! filter_level )
return ;
@ -1349,6 +1355,7 @@ static void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8Macroblock *mb, int
static void filter_mb_row ( VP8Context * s , int mb_y )
{
VP8FilterStrength * f = s - > filter_strength ;
VP8Macroblock * mb = s - > macroblocks + mb_y * s - > mb_stride ;
uint8_t * dst [ 3 ] = {
s - > framep [ VP56_FRAME_CURRENT ] - > data [ 0 ] + 16 * mb_y * s - > linesize ,
@ -1359,7 +1366,7 @@ static void filter_mb_row(VP8Context *s, int mb_y)
for ( mb_x = 0 ; mb_x < s - > mb_width ; mb_x + + ) {
backup_mb_border ( s - > top_border [ mb_x + 1 ] , dst [ 0 ] , dst [ 1 ] , dst [ 2 ] , s - > linesize , s - > uvlinesize , 0 ) ;
filter_mb ( s , dst , mb + + , mb_x , mb_y ) ;
filter_mb ( s , dst , mb + + , f + + , mb_x , mb_y ) ;
dst [ 0 ] + = 16 ;
dst [ 1 ] + = 8 ;
dst [ 2 ] + = 8 ;
@ -1368,13 +1375,14 @@ static void filter_mb_row(VP8Context *s, int mb_y)
static void filter_mb_row_simple ( VP8Context * s , int mb_y )
{
uint8_t * dst = s - > framep [ VP56_FRAME_CURRENT ] - > data [ 0 ] + 16 * mb_y * s - > linesize ;
VP8FilterStrength * f = s - > filter_strength ;
VP8Macroblock * mb = s - > macroblocks + mb_y * s - > mb_stride ;
uint8_t * dst = s - > framep [ VP56_FRAME_CURRENT ] - > data [ 0 ] + 16 * mb_y * s - > linesize ;
int mb_x ;
for ( mb_x = 0 ; mb_x < s - > mb_width ; mb_x + + ) {
backup_mb_border ( s - > top_border [ mb_x + 1 ] , dst , NULL , NULL , s - > linesize , 0 , 1 ) ;
filter_mb_simple ( s , dst , mb + + , mb_x , mb_y ) ;
filter_mb_simple ( s , dst , mb + + , f + + , mb_x , mb_y ) ;
dst + = 16 ;
}
}
@ -1497,6 +1505,9 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
}
}
if ( s - > deblock_filter )
filter_level_for_mb ( s , mb , & s - > filter_strength [ mb_x ] ) ;
dst [ 0 ] + = 16 ;
dst [ 1 ] + = 8 ;
dst [ 2 ] + = 8 ;