ref: 88fa7efb1c6430f07ea93c736d85489fb8a8f1ae
parent: 55a2abfe31b82af13a77c3dc89913774f667b898
author: Jerome Jiang <jianj@google.com>
date: Mon Jun 11 07:05:36 EDT 2018
vp9 svc: Denoise golden when it's a temporal ref. When golden was the inter-layer reference, a block that selected the golden ref would not be denoised. But when golden is used as a second temporal reference then we should denoise blocks that select the golden reference. This changes allows for that. Change-Id: Ifdea2ac88f6a74f73520fedcd7fec2f32c559ec9
--- a/vp9/encoder/vp9_denoiser.c
+++ b/vp9/encoder/vp9_denoiser.c
@@ -189,7 +189,7 @@
int increase_denoising, int mi_row, int mi_col, PICK_MODE_CONTEXT *ctx,
int motion_magnitude, int is_skin, int *zeromv_filter, int consec_zeromv,
int num_spatial_layers, int width, int lst_fb_idx, int gld_fb_idx,
- int use_svc, int spatial_layer) {
+ int use_svc, int spatial_layer, int use_gf_temporal_ref) {
const int sse_diff = (ctx->newmv_sse == UINT_MAX)
? 0
: ((int)ctx->zeromv_sse - (int)ctx->newmv_sse);
@@ -220,7 +220,8 @@
// If the best reference frame uses inter-prediction and there is enough of a
// difference in sum-squared-error, use it.
if (frame != INTRA_FRAME && frame != ALTREF_FRAME &&
- (frame != GOLDEN_FRAME || num_spatial_layers == 1) &&
+ (frame != GOLDEN_FRAME || num_spatial_layers == 1 ||
+ use_gf_temporal_ref) &&
sse_diff > sse_diff_thresh(bs, increase_denoising, motion_magnitude)) {
mi->ref_frame[0] = ctx->best_reference_frame;
mi->mode = ctx->best_sse_inter_mode;
@@ -230,7 +231,8 @@
frame = ctx->best_zeromv_reference_frame;
ctx->newmv_sse = ctx->zeromv_sse;
// Bias to last reference.
- if (num_spatial_layers > 1 || frame == ALTREF_FRAME ||
+ if ((num_spatial_layers > 1 && !use_gf_temporal_ref) ||
+ frame == ALTREF_FRAME ||
(frame != LAST_FRAME &&
((ctx->zeromv_lastref_sse<(5 * ctx->zeromv_sse)>> 2) ||
denoiser->denoising_level >= kDenHigh))) {
@@ -326,7 +328,8 @@
void vp9_denoiser_denoise(VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, int mi_col,
BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx,
- VP9_DENOISER_DECISION *denoiser_decision) {
+ VP9_DENOISER_DECISION *denoiser_decision,
+ int use_gf_temporal_ref) {
int mv_col, mv_row;
int motion_magnitude = 0;
int zeromv_filter = 0;
@@ -397,7 +400,8 @@
&cpi->common, denoiser, mb, bs, increase_denoising, mi_row, mi_col, ctx,
motion_magnitude, is_skin, &zeromv_filter, consec_zeromv,
cpi->svc.number_spatial_layers, cpi->Source->y_width, cpi->lst_fb_idx,
- cpi->gld_fb_idx, cpi->use_svc, cpi->svc.spatial_layer_id);
+ cpi->gld_fb_idx, cpi->use_svc, cpi->svc.spatial_layer_id,
+ use_gf_temporal_ref);
if (decision == FILTER_BLOCK) {
decision = vp9_denoiser_filter(src.buf, src.stride, mc_avg_start,
--- a/vp9/encoder/vp9_denoiser.h
+++ b/vp9/encoder/vp9_denoiser.h
@@ -77,7 +77,8 @@
void vp9_denoiser_denoise(struct VP9_COMP *cpi, MACROBLOCK *mb, int mi_row,
int mi_col, BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx,
- VP9_DENOISER_DECISION *denoiser_decision);
+ VP9_DENOISER_DECISION *denoiser_decision,
+ int use_gf_temporal_ref);
void vp9_denoiser_reset_frame_stats(PICK_MODE_CONTEXT *ctx);
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1497,7 +1497,7 @@
int skip_ref_find_pred[4] = { 0 };
unsigned int sse_zeromv_normalized = UINT_MAX;
unsigned int best_sse_sofar = UINT_MAX;
- int gf_is_longterm_ref = 0;
+ int gf_temporal_ref = 0;
#if CONFIG_VP9_TEMPORAL_DENOISING
VP9_PICKMODE_CTX_DEN ctx_den;
int64_t zero_last_cost_orig = INT64_MAX;
@@ -1542,7 +1542,7 @@
if (!cpi->use_svc ||
(svc->use_gf_temporal_ref_current_layer &&
!svc->layer_context[svc->temporal_layer_id].is_key_frame))
- gf_is_longterm_ref = 1;
+ gf_temporal_ref = 1;
init_ref_frame_cost(cm, xd, ref_frame_cost);
memset(&mode_checked[0][0], 0, MB_MODE_COUNT * MAX_REF_FRAMES);
@@ -1616,7 +1616,7 @@
}
#endif
- if (cpi->rc.frames_since_golden == 0 && gf_is_longterm_ref &&
+ if (cpi->rc.frames_since_golden == 0 && gf_temporal_ref &&
!cpi->rc.alt_ref_gf_group && !cpi->rc.last_frame_is_src_altref) {
usable_ref_frame = LAST_FRAME;
} else {
@@ -1643,7 +1643,7 @@
// For svc mode, on spatial_layer_id > 0: if the reference has different scale
// constrain the inter mode to only test zero motion.
if (cpi->use_svc && svc->force_zero_mode_spatial_ref &&
- svc->spatial_layer_id > 0 && !gf_is_longterm_ref) {
+ svc->spatial_layer_id > 0 && !gf_temporal_ref) {
if (cpi->ref_frame_flags & flag_list[LAST_FRAME]) {
struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf;
if (vp9_is_scaled(sf)) {
@@ -1723,7 +1723,7 @@
if (cpi->use_svc && svc->spatial_layer_id > 0 &&
svc_force_zero_mode[inter_layer_ref - 1] &&
svc->downsample_filter_phase[svc->spatial_layer_id - 1] == 8 &&
- !gf_is_longterm_ref) {
+ !gf_temporal_ref) {
svc_mv_col = -4;
svc_mv_row = -4;
flag_svc_subpel = 1;
@@ -1796,7 +1796,7 @@
// For SVC, skip the golden (spatial) reference search if sse of zeromv_last
// is below threshold.
- if (cpi->use_svc && ref_frame == GOLDEN_FRAME && !gf_is_longterm_ref &&
+ if (cpi->use_svc && ref_frame == GOLDEN_FRAME && !gf_temporal_ref &&
sse_zeromv_normalized < thresh_svc_skip_golden)
continue;
@@ -1916,7 +1916,7 @@
if (frame_mv[this_mode][ref_frame].as_int != 0) continue;
if (this_mode == NEWMV && !force_mv_inter_layer) {
- if (ref_frame > LAST_FRAME && gf_is_longterm_ref &&
+ if (ref_frame > LAST_FRAME && gf_temporal_ref &&
cpi->oxcf.rc_mode == VPX_CBR) {
int tmp_sad;
uint32_t dis;
@@ -2284,7 +2284,7 @@
// layer is chosen as the reference. Always perform intra prediction if
// LAST is the only reference, or is_key_frame is set, or on base
// temporal layer.
- if (svc->spatial_layer_id && !gf_is_longterm_ref) {
+ if (svc->spatial_layer_id && !gf_temporal_ref) {
perform_intra_pred =
svc->temporal_layer_id == 0 ||
svc->layer_context[svc->temporal_layer_id].is_key_frame ||
@@ -2459,7 +2459,8 @@
frame_mv, reuse_inter_pred, best_tx_size,
best_mode, best_ref_frame, best_pred_filter,
best_mode_skip_txfm);
- vp9_denoiser_denoise(cpi, x, mi_row, mi_col, bsize, ctx, &decision);
+ vp9_denoiser_denoise(cpi, x, mi_row, mi_col, bsize, ctx, &decision,
+ gf_temporal_ref);
recheck_zeromv_after_denoising(cpi, mi, x, xd, decision, &ctx_den, yv12_mb,
&best_rdc, bsize, mi_row, mi_col);
best_ref_frame = ctx_den.best_ref_frame;