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
This commit is contained in:
@@ -189,7 +189,7 @@ static VP9_DENOISER_DECISION perform_motion_compensation(
|
||||
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 @@ static VP9_DENOISER_DECISION perform_motion_compensation(
|
||||
// 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 @@ static VP9_DENOISER_DECISION perform_motion_compensation(
|
||||
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 @@ static VP9_DENOISER_DECISION perform_motion_compensation(
|
||||
|
||||
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 @@ void vp9_denoiser_denoise(VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, int mi_col,
|
||||
&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,
|
||||
|
||||
@@ -77,7 +77,8 @@ void vp9_denoiser_update_frame_info(
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -1497,7 +1497,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
|
||||
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 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
|
||||
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 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
|
||||
}
|
||||
#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 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
|
||||
// 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 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
|
||||
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 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
|
||||
|
||||
// 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 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
|
||||
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 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
|
||||
// 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 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user