summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
authorJerome Jiang <jianj@google.com>2018-12-04 23:34:20 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-12-04 23:34:20 +0000
commit51fe234ad1c021d41a0e74d70ae02a72067db6af (patch)
tree198583b0349f416fb72f252d631ca58601aa527b /vp9
parentc6a89211724ca80c7c39a32167d3de6fd0c2c1bf (diff)
parent28345f9730e476eebd23c41c1abd71fc45b74d9a (diff)
downloadlibvpx-51fe234ad1c021d41a0e74d70ae02a72067db6af.tar
libvpx-51fe234ad1c021d41a0e74d70ae02a72067db6af.tar.gz
libvpx-51fe234ad1c021d41a0e74d70ae02a72067db6af.tar.bz2
libvpx-51fe234ad1c021d41a0e74d70ae02a72067db6af.zip
Merge "vp9: force refresh of long term ref when denoiser reset."
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_denoiser.c33
-rw-r--r--vp9/encoder/vp9_denoiser.h5
-rw-r--r--vp9/encoder/vp9_encoder.c4
-rw-r--r--vp9/encoder/vp9_noise_estimate.c4
-rw-r--r--vp9/encoder/vp9_pickmode.c8
-rw-r--r--vp9/encoder/vp9_svc_layercontext.c10
-rw-r--r--vp9/encoder/vp9_svc_layercontext.h4
7 files changed, 55 insertions, 13 deletions
diff --git a/vp9/encoder/vp9_denoiser.c b/vp9/encoder/vp9_denoiser.c
index b70890e68..2820b71b4 100644
--- a/vp9/encoder/vp9_denoiser.c
+++ b/vp9/encoder/vp9_denoiser.c
@@ -692,6 +692,7 @@ int vp9_denoiser_alloc(VP9_COMMON *cm, struct SVC *svc, VP9_DENOISER *denoiser,
denoiser->denoising_level = kDenLow;
denoiser->prev_denoising_level = kDenLow;
denoiser->reset = 0;
+ denoiser->current_denoiser_frame = 0;
return 0;
}
@@ -716,13 +717,29 @@ void vp9_denoiser_free(VP9_DENOISER *denoiser) {
vpx_free_frame_buffer(&denoiser->last_source);
}
-void vp9_denoiser_set_noise_level(VP9_DENOISER *denoiser, int noise_level) {
+static void force_refresh_longterm_ref(VP9_COMP *const cpi) {
+ SVC *const svc = &cpi->svc;
+ // If long term reference is used, force refresh of that slot, so
+ // denoiser buffer for long term reference stays in sync.
+ if (svc->use_gf_temporal_ref_current_layer) {
+ int index = svc->spatial_layer_id;
+ if (svc->number_spatial_layers == 3) index = svc->spatial_layer_id - 1;
+ assert(index >= 0);
+ cpi->alt_fb_idx = svc->buffer_gf_temporal_ref[index].idx;
+ cpi->refresh_alt_ref_frame = 1;
+ }
+}
+
+void vp9_denoiser_set_noise_level(VP9_COMP *const cpi, int noise_level) {
+ VP9_DENOISER *const denoiser = &cpi->denoiser;
denoiser->denoising_level = noise_level;
if (denoiser->denoising_level > kDenLowLow &&
- denoiser->prev_denoising_level == kDenLowLow)
+ denoiser->prev_denoising_level == kDenLowLow) {
denoiser->reset = 1;
- else
+ force_refresh_longterm_ref(cpi);
+ } else {
denoiser->reset = 0;
+ }
denoiser->prev_denoising_level = denoiser->denoising_level;
}
@@ -754,14 +771,24 @@ int64_t vp9_scale_acskip_thresh(int64_t threshold,
return threshold;
}
+void vp9_denoiser_reset_on_first_frame(VP9_COMP *const cpi) {
+ if (vp9_denoise_svc_non_key(cpi) &&
+ cpi->denoiser.current_denoiser_frame == 0) {
+ cpi->denoiser.reset = 1;
+ force_refresh_longterm_ref(cpi);
+ }
+}
+
void vp9_denoiser_update_ref_frame(VP9_COMP *const cpi) {
VP9_COMMON *const cm = &cpi->common;
SVC *const svc = &cpi->svc;
+
if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi) &&
cpi->denoiser.denoising_level > kDenLowLow) {
int svc_refresh_denoiser_buffers = 0;
int denoise_svc_second_layer = 0;
FRAME_TYPE frame_type = cm->intra_only ? KEY_FRAME : cm->frame_type;
+ cpi->denoiser.current_denoiser_frame++;
if (cpi->use_svc) {
const int svc_buf_shift =
svc->number_spatial_layers - svc->spatial_layer_id == 2
diff --git a/vp9/encoder/vp9_denoiser.h b/vp9/encoder/vp9_denoiser.h
index 2362c4f50..1973e9898 100644
--- a/vp9/encoder/vp9_denoiser.h
+++ b/vp9/encoder/vp9_denoiser.h
@@ -50,6 +50,7 @@ typedef struct vp9_denoiser {
int reset;
int num_ref_frames;
int num_layers;
+ unsigned int current_denoiser_frame;
VP9_DENOISER_LEVEL denoising_level;
VP9_DENOISER_LEVEL prev_denoising_level;
} VP9_DENOISER;
@@ -111,7 +112,9 @@ static INLINE int total_adj_strong_thresh(BLOCK_SIZE bs,
void vp9_denoiser_free(VP9_DENOISER *denoiser);
-void vp9_denoiser_set_noise_level(VP9_DENOISER *denoiser, int noise_level);
+void vp9_denoiser_set_noise_level(struct VP9_COMP *const cpi, int noise_level);
+
+void vp9_denoiser_reset_on_first_frame(struct VP9_COMP *const cpi);
int64_t vp9_scale_part_thresh(int64_t threshold, VP9_DENOISER_LEVEL noise_level,
int content_state, int temporal_layer_id);
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 746f234e2..a73185623 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3815,6 +3815,10 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
cm->mi_rows * cm->mi_cols * sizeof(*cpi->consec_zero_mv));
}
+#if CONFIG_VP9_TEMPORAL_DENOISING
+ if (cpi->oxcf.noise_sensitivity > 0 && cpi->use_svc)
+ vp9_denoiser_reset_on_first_frame(cpi);
+#endif
vp9_update_noise_estimate(cpi);
// Scene detection is always used for VBR mode or screen-content case.
diff --git a/vp9/encoder/vp9_noise_estimate.c b/vp9/encoder/vp9_noise_estimate.c
index 8c9a40f55..fc189dbb1 100644
--- a/vp9/encoder/vp9_noise_estimate.c
+++ b/vp9/encoder/vp9_noise_estimate.c
@@ -159,7 +159,7 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) {
#if CONFIG_VP9_TEMPORAL_DENOISING
if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi) &&
cpi->svc.current_superframe > 1) {
- vp9_denoiser_set_noise_level(&cpi->denoiser, ne->level);
+ vp9_denoiser_set_noise_level(cpi, ne->level);
copy_frame(&cpi->denoiser.last_source, cpi->Source);
}
#endif
@@ -269,7 +269,7 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) {
ne->level = vp9_noise_estimate_extract_level(ne);
#if CONFIG_VP9_TEMPORAL_DENOISING
if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi))
- vp9_denoiser_set_noise_level(&cpi->denoiser, ne->level);
+ vp9_denoiser_set_noise_level(cpi, ne->level);
#endif
}
}
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index 1324b5bc8..fe8f24444 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1815,13 +1815,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
#if CONFIG_VP9_TEMPORAL_DENOISING
if (cpi->oxcf.noise_sensitivity > 0) {
- if (cpi->use_svc) {
- int layer =
- LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id,
- svc->number_temporal_layers);
- LAYER_CONTEXT *lc = &svc->layer_context[layer];
- denoise_svc_pickmode = denoise_svc(cpi) && !lc->is_key_frame;
- }
+ if (cpi->use_svc) denoise_svc_pickmode = vp9_denoise_svc_non_key(cpi);
if (cpi->denoiser.denoising_level > kDenLowLow && denoise_svc_pickmode)
vp9_denoiser_reset_frame_stats(ctx);
}
diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c
index 21b920f11..510087580 100644
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -1106,6 +1106,16 @@ void vp9_svc_assert_constraints_pattern(VP9_COMP *const cpi) {
}
}
+#if CONFIG_VP9_TEMPORAL_DENOISING
+int vp9_denoise_svc_non_key(VP9_COMP *const cpi) {
+ int layer =
+ LAYER_IDS_TO_IDX(cpi->svc.spatial_layer_id, cpi->svc.temporal_layer_id,
+ cpi->svc.number_temporal_layers);
+ LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer];
+ return denoise_svc(cpi) && !lc->is_key_frame;
+}
+#endif
+
void vp9_svc_check_spatial_layer_sync(VP9_COMP *const cpi) {
SVC *const svc = &cpi->svc;
// Only for superframes whose base is not key, as those are
diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h
index 945312044..f1f2457b2 100644
--- a/vp9/encoder/vp9_svc_layercontext.h
+++ b/vp9/encoder/vp9_svc_layercontext.h
@@ -235,6 +235,10 @@ struct lookahead_entry *vp9_svc_lookahead_pop(struct VP9_COMP *const cpi,
// Start a frame and initialize svc parameters
int vp9_svc_start_frame(struct VP9_COMP *const cpi);
+#if CONFIG_VP9_TEMPORAL_DENOISING
+int vp9_denoise_svc_non_key(struct VP9_COMP *const cpi);
+#endif
+
void vp9_copy_flags_ref_update_idx(struct VP9_COMP *const cpi);
int vp9_one_pass_cbr_svc_start_layer(struct VP9_COMP *const cpi);