mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 06:08:21 +01:00
filtering: precompute ilimit and hev_threshold
no speed change, just simplifying the logic Change-Id: I518800494428596733d4fbae69072049828aec3c
This commit is contained in:
parent
18f992ec0f
commit
43148b6cd2
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user