filtering: precompute ilimit and hev_threshold

no speed change, just simplifying the logic

Change-Id: I518800494428596733d4fbae69072049828aec3c
This commit is contained in:
skal 2013-10-28 13:37:33 +01:00
parent 18f992ec0f
commit 43148b6cd2
2 changed files with 24 additions and 27 deletions

View File

@ -34,26 +34,18 @@ static void ReconstructRow(const VP8Decoder* const dec,
// U/V, so it's 8 samples total (because of the 2x upsampling). // U/V, so it's 8 samples total (because of the 2x upsampling).
static const uint8_t kFilterExtraRows[3] = { 0, 2, 8 }; static const uint8_t kFilterExtraRows[3] = { 0, 2, 8 };
static WEBP_INLINE int hev_thresh_from_level(int level, int keyframe) {
if (keyframe) {
return (level >= 40) ? 2 : (level >= 15) ? 1 : 0;
} else {
return (level >= 40) ? 3 : (level >= 20) ? 2 : (level >= 15) ? 1 : 0;
}
}
static void DoFilter(const VP8Decoder* const dec, int mb_x, int mb_y) { static void DoFilter(const VP8Decoder* const dec, int mb_x, int mb_y) {
const VP8ThreadContext* const ctx = &dec->thread_ctx_; const VP8ThreadContext* const ctx = &dec->thread_ctx_;
const int cache_id = ctx->id_; const int cache_id = ctx->id_;
const int y_bps = dec->cache_y_stride_; const int y_bps = dec->cache_y_stride_;
const VP8FInfo* const f_info = ctx->f_info_ + mb_x; const VP8FInfo* const f_info = ctx->f_info_ + mb_x;
uint8_t* const y_dst = dec->cache_y_ + cache_id * 16 * y_bps + mb_x * 16; uint8_t* const y_dst = dec->cache_y_ + cache_id * 16 * y_bps + mb_x * 16;
const int level = f_info->f_level_;
const int ilevel = f_info->f_ilevel_; const int ilevel = f_info->f_ilevel_;
const int limit = 2 * level + ilevel; const int limit = f_info->f_limit_;
if (level == 0) { if (limit == 0) {
return; return;
} }
assert(limit >= 3);
if (dec->filter_type_ == 1) { // simple if (dec->filter_type_ == 1) { // simple
if (mb_x > 0) { if (mb_x > 0) {
VP8SimpleHFilter16(y_dst, y_bps, limit + 4); VP8SimpleHFilter16(y_dst, y_bps, limit + 4);
@ -71,8 +63,7 @@ static void DoFilter(const VP8Decoder* const dec, int mb_x, int mb_y) {
const int uv_bps = dec->cache_uv_stride_; const int uv_bps = dec->cache_uv_stride_;
uint8_t* const u_dst = dec->cache_u_ + cache_id * 8 * uv_bps + mb_x * 8; uint8_t* const u_dst = dec->cache_u_ + cache_id * 8 * uv_bps + mb_x * 8;
uint8_t* const v_dst = dec->cache_v_ + cache_id * 8 * uv_bps + mb_x * 8; uint8_t* const v_dst = dec->cache_v_ + cache_id * 8 * uv_bps + mb_x * 8;
const int hev_thresh = const int hev_thresh = f_info->hev_thresh_;
hev_thresh_from_level(level, dec->frm_hdr_.key_frame_);
if (mb_x > 0) { if (mb_x > 0) {
VP8HFilter16(y_dst, y_bps, limit + 4, ilevel, hev_thresh); VP8HFilter16(y_dst, y_bps, limit + 4, ilevel, hev_thresh);
VP8HFilter8(u_dst, v_dst, uv_bps, limit + 4, ilevel, hev_thresh); VP8HFilter8(u_dst, v_dst, uv_bps, limit + 4, ilevel, hev_thresh);
@ -132,19 +123,25 @@ static void PrecomputeFilterStrengths(VP8Decoder* const dec) {
} }
} }
level = (level < 0) ? 0 : (level > 63) ? 63 : level; level = (level < 0) ? 0 : (level > 63) ? 63 : level;
info->f_level_ = level; if (level > 0) {
int ilevel = level;
if (hdr->sharpness_ > 0) { if (hdr->sharpness_ > 0) {
if (hdr->sharpness_ > 4) { if (hdr->sharpness_ > 4) {
level >>= 2; ilevel >>= 2;
} else { } else {
level >>= 1; ilevel >>= 1;
} }
if (level > 9 - hdr->sharpness_) { if (ilevel > 9 - hdr->sharpness_) {
level = 9 - hdr->sharpness_; ilevel = 9 - hdr->sharpness_;
} }
} }
info->f_ilevel_ = (level < 1) ? 1 : level; if (ilevel < 1) ilevel = 1;
info->f_ilevel_ = ilevel;
info->f_limit_ = 2 * level + ilevel;
info->hev_thresh_ = (level >= 40) ? 2 : (level >= 15) ? 1 : 0;
} else {
info->f_limit_ = 0; // no filtering
}
info->f_inner_ = i4x4; info->f_inner_ = i4x4;
} }
} }

View File

@ -164,10 +164,10 @@ typedef struct {
// Informations about the macroblocks. // Informations about the macroblocks.
typedef struct { // filter specs typedef struct { // filter specs
uint8_t f_level_; // filter strength: 0..63 uint8_t f_limit_; // filter limit in [3..189], or 0 if no filtering
uint8_t f_ilevel_; // inner limit: 1..63 uint8_t f_ilevel_; // inner limit in [1..63]
uint8_t f_inner_; // do inner filtering? uint8_t f_inner_; // do inner filtering?
uint8_t pad_; // mostly needed for struct aligning on ARM uint8_t hev_thresh_; // high edge variance threshold in [0..2]
} VP8FInfo; } VP8FInfo;
typedef struct { // Top/Left Contexts used for syntax-parsing typedef struct { // Top/Left Contexts used for syntax-parsing