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 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 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 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)
|
const int sse_diff = (ctx->newmv_sse == UINT_MAX)
|
||||||
? 0
|
? 0
|
||||||
: ((int)ctx->zeromv_sse - (int)ctx->newmv_sse);
|
: ((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
|
// If the best reference frame uses inter-prediction and there is enough of a
|
||||||
// difference in sum-squared-error, use it.
|
// difference in sum-squared-error, use it.
|
||||||
if (frame != INTRA_FRAME && frame != ALTREF_FRAME &&
|
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)) {
|
sse_diff > sse_diff_thresh(bs, increase_denoising, motion_magnitude)) {
|
||||||
mi->ref_frame[0] = ctx->best_reference_frame;
|
mi->ref_frame[0] = ctx->best_reference_frame;
|
||||||
mi->mode = ctx->best_sse_inter_mode;
|
mi->mode = ctx->best_sse_inter_mode;
|
||||||
@@ -230,7 +231,8 @@ static VP9_DENOISER_DECISION perform_motion_compensation(
|
|||||||
frame = ctx->best_zeromv_reference_frame;
|
frame = ctx->best_zeromv_reference_frame;
|
||||||
ctx->newmv_sse = ctx->zeromv_sse;
|
ctx->newmv_sse = ctx->zeromv_sse;
|
||||||
// Bias to last reference.
|
// 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 &&
|
(frame != LAST_FRAME &&
|
||||||
((ctx->zeromv_lastref_sse<(5 * ctx->zeromv_sse)>> 2) ||
|
((ctx->zeromv_lastref_sse<(5 * ctx->zeromv_sse)>> 2) ||
|
||||||
denoiser->denoising_level >= kDenHigh))) {
|
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,
|
void vp9_denoiser_denoise(VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, int mi_col,
|
||||||
BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx,
|
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 mv_col, mv_row;
|
||||||
int motion_magnitude = 0;
|
int motion_magnitude = 0;
|
||||||
int zeromv_filter = 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,
|
&cpi->common, denoiser, mb, bs, increase_denoising, mi_row, mi_col, ctx,
|
||||||
motion_magnitude, is_skin, &zeromv_filter, consec_zeromv,
|
motion_magnitude, is_skin, &zeromv_filter, consec_zeromv,
|
||||||
cpi->svc.number_spatial_layers, cpi->Source->y_width, cpi->lst_fb_idx,
|
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) {
|
if (decision == FILTER_BLOCK) {
|
||||||
decision = vp9_denoiser_filter(src.buf, src.stride, mc_avg_start,
|
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,
|
void vp9_denoiser_denoise(struct VP9_COMP *cpi, MACROBLOCK *mb, int mi_row,
|
||||||
int mi_col, BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx,
|
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);
|
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 };
|
int skip_ref_find_pred[4] = { 0 };
|
||||||
unsigned int sse_zeromv_normalized = UINT_MAX;
|
unsigned int sse_zeromv_normalized = UINT_MAX;
|
||||||
unsigned int best_sse_sofar = 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
|
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||||
VP9_PICKMODE_CTX_DEN ctx_den;
|
VP9_PICKMODE_CTX_DEN ctx_den;
|
||||||
int64_t zero_last_cost_orig = INT64_MAX;
|
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 ||
|
if (!cpi->use_svc ||
|
||||||
(svc->use_gf_temporal_ref_current_layer &&
|
(svc->use_gf_temporal_ref_current_layer &&
|
||||||
!svc->layer_context[svc->temporal_layer_id].is_key_frame))
|
!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);
|
init_ref_frame_cost(cm, xd, ref_frame_cost);
|
||||||
memset(&mode_checked[0][0], 0, MB_MODE_COUNT * MAX_REF_FRAMES);
|
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
|
#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) {
|
!cpi->rc.alt_ref_gf_group && !cpi->rc.last_frame_is_src_altref) {
|
||||||
usable_ref_frame = LAST_FRAME;
|
usable_ref_frame = LAST_FRAME;
|
||||||
} else {
|
} 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
|
// For svc mode, on spatial_layer_id > 0: if the reference has different scale
|
||||||
// constrain the inter mode to only test zero motion.
|
// constrain the inter mode to only test zero motion.
|
||||||
if (cpi->use_svc && svc->force_zero_mode_spatial_ref &&
|
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]) {
|
if (cpi->ref_frame_flags & flag_list[LAST_FRAME]) {
|
||||||
struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf;
|
struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf;
|
||||||
if (vp9_is_scaled(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 &&
|
if (cpi->use_svc && svc->spatial_layer_id > 0 &&
|
||||||
svc_force_zero_mode[inter_layer_ref - 1] &&
|
svc_force_zero_mode[inter_layer_ref - 1] &&
|
||||||
svc->downsample_filter_phase[svc->spatial_layer_id - 1] == 8 &&
|
svc->downsample_filter_phase[svc->spatial_layer_id - 1] == 8 &&
|
||||||
!gf_is_longterm_ref) {
|
!gf_temporal_ref) {
|
||||||
svc_mv_col = -4;
|
svc_mv_col = -4;
|
||||||
svc_mv_row = -4;
|
svc_mv_row = -4;
|
||||||
flag_svc_subpel = 1;
|
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
|
// For SVC, skip the golden (spatial) reference search if sse of zeromv_last
|
||||||
// is below threshold.
|
// 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)
|
sse_zeromv_normalized < thresh_svc_skip_golden)
|
||||||
continue;
|
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 (frame_mv[this_mode][ref_frame].as_int != 0) continue;
|
||||||
|
|
||||||
if (this_mode == NEWMV && !force_mv_inter_layer) {
|
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) {
|
cpi->oxcf.rc_mode == VPX_CBR) {
|
||||||
int tmp_sad;
|
int tmp_sad;
|
||||||
uint32_t dis;
|
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
|
// 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
|
// LAST is the only reference, or is_key_frame is set, or on base
|
||||||
// temporal layer.
|
// temporal layer.
|
||||||
if (svc->spatial_layer_id && !gf_is_longterm_ref) {
|
if (svc->spatial_layer_id && !gf_temporal_ref) {
|
||||||
perform_intra_pred =
|
perform_intra_pred =
|
||||||
svc->temporal_layer_id == 0 ||
|
svc->temporal_layer_id == 0 ||
|
||||||
svc->layer_context[svc->temporal_layer_id].is_key_frame ||
|
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,
|
frame_mv, reuse_inter_pred, best_tx_size,
|
||||||
best_mode, best_ref_frame, best_pred_filter,
|
best_mode, best_ref_frame, best_pred_filter,
|
||||||
best_mode_skip_txfm);
|
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,
|
recheck_zeromv_after_denoising(cpi, mi, x, xd, decision, &ctx_den, yv12_mb,
|
||||||
&best_rdc, bsize, mi_row, mi_col);
|
&best_rdc, bsize, mi_row, mi_col);
|
||||||
best_ref_frame = ctx_den.best_ref_frame;
|
best_ref_frame = ctx_den.best_ref_frame;
|
||||||
|
|||||||
Reference in New Issue
Block a user