src->y_buffer = tmp_buf;
}
-void vp9_denoiser_update_frame_info(VP9_DENOISER *denoiser,
- YV12_BUFFER_CONFIG src,
- FRAME_TYPE frame_type,
- int refresh_alt_ref_frame,
- int refresh_golden_frame,
- int refresh_last_frame, int resized) {
+void vp9_denoiser_update_frame_info(
+ VP9_DENOISER *denoiser, YV12_BUFFER_CONFIG src, FRAME_TYPE frame_type,
+ int refresh_alt_ref_frame, int refresh_golden_frame, int refresh_last_frame,
+ int resized, int svc_base_is_key) {
// Copy source into denoised reference buffers on KEY_FRAME or
- // if the just encoded frame was resized.
- if (frame_type == KEY_FRAME || resized != 0 || denoiser->reset) {
+ // if the just encoded frame was resized. For SVC, copy source if the base
+ // spatial layer was key frame.
+ if (frame_type == KEY_FRAME || resized != 0 || denoiser->reset ||
+ svc_base_is_key) {
int i;
// Start at 1 so as not to overwrite the INTRA_FRAME
for (i = 1; i < MAX_REF_FRAMES; ++i)
struct VP9_COMP;
-void vp9_denoiser_update_frame_info(VP9_DENOISER *denoiser,
- YV12_BUFFER_CONFIG src,
- FRAME_TYPE frame_type,
- int refresh_alt_ref_frame,
- int refresh_golden_frame,
- int refresh_last_frame, int resized);
+void vp9_denoiser_update_frame_info(
+ VP9_DENOISER *denoiser, YV12_BUFFER_CONFIG src, FRAME_TYPE frame_type,
+ int refresh_alt_ref_frame, int refresh_golden_frame, int refresh_last_frame,
+ int resized, int svc_base_is_key);
void vp9_denoiser_denoise(struct VP9_COMP *cpi, MACROBLOCK *mb, int mi_row,
int mi_col, BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx,
#if CONFIG_VP9_TEMPORAL_DENOISING
if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi) &&
cpi->denoiser.denoising_level > kDenLowLow) {
+ int svc_base_is_key = 0;
+ if (cpi->use_svc) {
+ 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];
+ svc_base_is_key = lc->is_key_frame;
+ }
vp9_denoiser_update_frame_info(
&cpi->denoiser, *cpi->Source, cpi->common.frame_type,
cpi->refresh_alt_ref_frame, cpi->refresh_golden_frame,
- cpi->refresh_last_frame, cpi->resize_pending);
+ cpi->refresh_last_frame, cpi->resize_pending, svc_base_is_key);
}
#endif
if (is_one_pass_cbr_svc(cpi)) {
// Force noise estimation to 0 and denoiser off if content has high motion.
ne->level = kLowLow;
#if CONFIG_VP9_TEMPORAL_DENOISING
- if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi))
+ if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi) &&
+ cpi->svc.current_superframe > 1)
vp9_denoiser_set_noise_level(&cpi->denoiser, ne->level);
#endif
return;
? VPXMIN(rc->avg_frame_qindex[INTER_FRAME],
rc->avg_frame_qindex[KEY_FRAME])
: rc->avg_frame_qindex[INTER_FRAME];
+ // For SVC if the current base spatial layer was key frame, use the QP from
+ // that base layer for ambient_qp.
+ if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) {
+ int layer = LAYER_IDS_TO_IDX(0, cpi->svc.temporal_layer_id,
+ cpi->svc.number_temporal_layers);
+ const LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer];
+ if (lc->is_key_frame) {
+ const RATE_CONTROL *lrc = &lc->rc;
+ ambient_qp = VPXMIN(ambient_qp, lrc->last_q[KEY_FRAME]);
+ }
+ }
active_worst_quality = VPXMIN(rc->worst_quality, ambient_qp * 5 >> 2);
if (rc->buffer_level > rc->optimal_buffer_level) {
// Adjust down.