History

vp9 svc: Allow denoising next to highest resolution.

Denoise 2 spatial layes at most. Add noise sensitivity level 2 for vp9 such that applications can control whether to denoise the second highest spatial layer. Add tests to cover this case.

Jerome Jiang committed 8 years ago

Commit c1e511f1 parent 14dbdd910 files · +210 −110Browse files

Unified · Split

10 files
  1. examples/vpx_temporal_svc_encoder.c +17 −9
  2. test/datarate_test.cc +21 −16
  3. vp9/encoder/vp9_denoiser.c +118 −61
  4. vp9/encoder/vp9_denoiser.h +10 −6
  5. vp9/encoder/vp9_encoder.c +16 −6
  6. vp9/encoder/vp9_encoder.h +1 −1
  7. vp9/encoder/vp9_noise_estimate.c +15 −6
  8. vp9/encoder/vp9_svc_layercontext.c +4 −3
  9. vp9/encoder/vp9_svc_layercontext.h +7 −1
  10. vpx/vp8cx.h +1 −1
examples/vpx_temporal_svc_encoder.c+17−9
@@ -32,13 +32,21 @@ static const char *exec_name; · 31 unmodified lines
3232
3333 void usage_exit(void) { exit(EXIT_FAILURE); }
3434
35−// Denoiser states, for temporal denoising.
36−enum denoiserState {
37− kDenoiserOff,
38− kDenoiserOnYOnly,
39− kDenoiserOnYUV,
40− kDenoiserOnYUVAggressive,
41− kDenoiserOnAdaptive
35+// Denoiser states for vp8, for temporal denoising.
36+enum denoiserStateVp8 {
37+ kVp8DenoiserOff,
38+ kVp8DenoiserOnYOnly,
39+ kVp8DenoiserOnYUV,
40+ kVp8DenoiserOnYUVAggressive,
41+ kVp8DenoiserOnAdaptive
42+};
43+
44+// Denoiser states for vp9, for temporal denoising.
45+enum denoiserStateVp9 {
46+ kVp9DenoiserOff,
47+ kVp9DenoiserOnYOnly,
48+ // For SVC: denoise the top two spatial layers.
49+ kVp9DenoiserOnYTwoSpatialLayers
4250 };
4351
4452 static int mode_to_num_layers[13] = { 1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3 };
@@ -755,7 +763,7 @@ int main(int argc, char **argv) { · 710 unmodified lines
755763
756764 if (strncmp(encoder->name, "vp8", 3) == 0) {
757765 vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
758− vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
766+ vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kVp8DenoiserOff);
759767 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
760768 vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
761769 #if VP8_ROI_MAP
@@ -772,7 +780,7 @@ int main(int argc, char **argv) { · 10 unmodified lines
772780 vpx_codec_control(&codec, VP9E_SET_GF_CBR_BOOST_PCT, 0);
773781 vpx_codec_control(&codec, VP9E_SET_FRAME_PARALLEL_DECODING, 0);
774782 vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
775− vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kDenoiserOff);
783+ vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kVp9DenoiserOff);
776784 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
777785 vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
778786 vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
test/datarate_test.cc+21−16
@@ -1449,24 +1449,29 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TLDenoiserOn) { · 1448 unmodified lines
14491449 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
14501450 // TODO(marpan): Check that effective_datarate for each layer hits the
14511451 // layer target_bitrate.
1452− for (int i = 600; i <= 1000; i += 200) {
1453− cfg_.rc_target_bitrate = i;
1454− ResetModel();
1455− denoiser_on_ = 1;
1456− assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1457− cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1458− ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1459− ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1460− << " The datarate for the file exceeds the target by too much!";
1461− ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
1462− << " The datarate for the file is lower than the target by too much!";
1452+ // For SVC, noise_sen = 1 means denoising only the top spatial layer
1453+ // noise_sen = 2 means denoising the two top spatial layers.
1454+ for (int noise_sen = 1; noise_sen <= 2; noise_sen++) {
1455+ for (int i = 600; i <= 1000; i += 200) {
1456+ cfg_.rc_target_bitrate = i;
1457+ ResetModel();
1458+ denoiser_on_ = noise_sen;
1459+ assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1460+ cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1461+ ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1462+ ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1463+ << " The datarate for the file exceeds the target by too much!";
1464+ ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
1465+ << " The datarate for the file is lower than the target by too much!";
14631466 #if CONFIG_VP9_DECODER
1464− // Number of temporal layers > 1, so half of the frames in this SVC pattern
1465− // will be non-reference frame and hence encoder will avoid loopfilter.
1466− // Since frame dropper is off, we can expcet 150 (half of the sequence)
1467− // mismatched frames.
1468− EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
1467+ // Number of temporal layers > 1, so half of the frames in this SVC
1468+ // pattern
1469+ // will be non-reference frame and hence encoder will avoid loopfilter.
1470+ // Since frame dropper is off, we can expcet 150 (half of the sequence)
1471+ // mismatched frames.
1472+ EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
14691473 #endif
1474+ }
14701475 }
14711476 }
14721477
vp9/encoder/vp9_denoiser.c+118−61
@@ -189,11 +189,12 @@ static VP9_DENOISER_DECISION perform_motion_compensation( · 188 unmodified lines
189189 int increase_denoising, int mi_row, int mi_col, PICK_MODE_CONTEXT *ctx,
190190 int motion_magnitude, int is_skin, int *zeromv_filter, int consec_zeromv,
191191 int num_spatial_layers, int width, int lst_fb_idx, int gld_fb_idx,
192− int use_svc) {
192+ int use_svc, int spatial_layer) {
193193 const int sse_diff = (ctx->newmv_sse == UINT_MAX)
194194 ? 0
195195 : ((int)ctx->zeromv_sse - (int)ctx->newmv_sse);
196196 int frame;
197+ int denoise_layer_idx = 0;
197198 MACROBLOCKD *filter_mbd = &mb->e_mbd;
198199 MODE_INFO *mi = filter_mbd->mi[0];
199200 MODE_INFO saved_mi;
@@ -254,6 +255,10 @@ static VP9_DENOISER_DECISION perform_motion_compensation( · 54 unmodified lines
254255 frame = lst_fb_idx + 1;
255256 else if (frame == GOLDEN_FRAME)
256257 frame = gld_fb_idx + 1;
258+ // Shift for the second spatial layer.
259+ if (num_spatial_layers - spatial_layer == 2)
260+ frame = frame + denoiser->num_ref_frames;
261+ denoise_layer_idx = num_spatial_layers - spatial_layer - 1;
257262 }
258263
259264 if (ctx->newmv_sse > sse_thresh(bs, increase_denoising)) {
@@ -289,18 +294,21 @@ static VP9_DENOISER_DECISION perform_motion_compensation( · 29 unmodified lines
289294 denoiser->running_avg_y[frame].uv_stride, mi_row, mi_col);
290295 filter_mbd->plane[2].pre[0].stride = denoiser->running_avg_y[frame].uv_stride;
291296
292− filter_mbd->plane[0].dst.buf =
293− block_start(denoiser->mc_running_avg_y.y_buffer,
294− denoiser->mc_running_avg_y.y_stride, mi_row, mi_col);
295− filter_mbd->plane[0].dst.stride = denoiser->mc_running_avg_y.y_stride;
296− filter_mbd->plane[1].dst.buf =
297− block_start(denoiser->mc_running_avg_y.u_buffer,
298− denoiser->mc_running_avg_y.uv_stride, mi_row, mi_col);
299− filter_mbd->plane[1].dst.stride = denoiser->mc_running_avg_y.uv_stride;
300− filter_mbd->plane[2].dst.buf =
301− block_start(denoiser->mc_running_avg_y.v_buffer,
302− denoiser->mc_running_avg_y.uv_stride, mi_row, mi_col);
303− filter_mbd->plane[2].dst.stride = denoiser->mc_running_avg_y.uv_stride;
297+ filter_mbd->plane[0].dst.buf = block_start(
298+ denoiser->mc_running_avg_y[denoise_layer_idx].y_buffer,
299+ denoiser->mc_running_avg_y[denoise_layer_idx].y_stride, mi_row, mi_col);
300+ filter_mbd->plane[0].dst.stride =
301+ denoiser->mc_running_avg_y[denoise_layer_idx].y_stride;
302+ filter_mbd->plane[1].dst.buf = block_start(
303+ denoiser->mc_running_avg_y[denoise_layer_idx].u_buffer,
304+ denoiser->mc_running_avg_y[denoise_layer_idx].uv_stride, mi_row, mi_col);
305+ filter_mbd->plane[1].dst.stride =
306+ denoiser->mc_running_avg_y[denoise_layer_idx].uv_stride;
307+ filter_mbd->plane[2].dst.buf = block_start(
308+ denoiser->mc_running_avg_y[denoise_layer_idx].v_buffer,
309+ denoiser->mc_running_avg_y[denoise_layer_idx].uv_stride, mi_row, mi_col);
310+ filter_mbd->plane[2].dst.stride =
311+ denoiser->mc_running_avg_y[denoise_layer_idx].uv_stride;
304312
305313 set_ref_ptrs(cm, filter_mbd, saved_frame, NONE);
306314 vp9_build_inter_predictors_sby(filter_mbd, mi_row, mi_col, bs);
@@ -324,9 +332,17 @@ void vp9_denoiser_denoise(VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, int mi_col, · 17 unmodified lines
324332 int zeromv_filter = 0;
325333 VP9_DENOISER *denoiser = &cpi->denoiser;
326334 VP9_DENOISER_DECISION decision = COPY_BLOCK;
327− YV12_BUFFER_CONFIG avg = denoiser->running_avg_y[INTRA_FRAME];
328− YV12_BUFFER_CONFIG mc_avg = denoiser->mc_running_avg_y;
335+
336+ const int shift =
337+ cpi->svc.number_spatial_layers - cpi->svc.spatial_layer_id == 2
338+ ? denoiser->num_ref_frames
339+ : 0;
340+ YV12_BUFFER_CONFIG avg = denoiser->running_avg_y[INTRA_FRAME + shift];
341+ const int denoise_layer_index =
342+ cpi->svc.number_spatial_layers - cpi->svc.spatial_layer_id - 1;
343+ YV12_BUFFER_CONFIG mc_avg = denoiser->mc_running_avg_y[denoise_layer_index];
329344 uint8_t *avg_start = block_start(avg.y_buffer, avg.y_stride, mi_row, mi_col);
345+
330346 uint8_t *mc_avg_start =
331347 block_start(mc_avg.y_buffer, mc_avg.y_stride, mi_row, mi_col);
332348 struct buf_2d src = mb->plane[0].src;
@@ -381,7 +397,7 @@ void vp9_denoiser_denoise(VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, int mi_col, · 48 unmodified lines
381397 &cpi->common, denoiser, mb, bs, increase_denoising, mi_row, mi_col, ctx,
382398 motion_magnitude, is_skin, &zeromv_filter, consec_zeromv,
383399 cpi->svc.number_spatial_layers, cpi->Source->y_width, cpi->lst_fb_idx,
384− cpi->gld_fb_idx, cpi->use_svc);
400+ cpi->gld_fb_idx, cpi->use_svc, cpi->svc.spatial_layer_id);
385401
386402 if (decision == FILTER_BLOCK) {
387403 decision = vp9_denoiser_filter(src.buf, src.stride, mc_avg_start,
@@ -432,7 +448,8 @@ void vp9_denoiser_update_frame_info( · 44 unmodified lines
432448 VP9_DENOISER *denoiser, YV12_BUFFER_CONFIG src, FRAME_TYPE frame_type,
433449 int refresh_alt_ref_frame, int refresh_golden_frame, int refresh_last_frame,
434450 int alt_fb_idx, int gld_fb_idx, int lst_fb_idx, int resized,
435− int svc_base_is_key) {
451+ int svc_base_is_key, int second_spatial_layer) {
452+ const int shift = second_spatial_layer ? denoiser->num_ref_frames : 0;
436453 // Copy source into denoised reference buffers on KEY_FRAME or
437454 // if the just encoded frame was resized. For SVC, copy source if the base
438455 // spatial layer was key frame.
@@ -441,8 +458,8 @@ void vp9_denoiser_update_frame_info( · 2 unmodified lines
441458 int i;
442459 // Start at 1 so as not to overwrite the INTRA_FRAME
443460 for (i = 1; i < denoiser->num_ref_frames; ++i) {
444− if (denoiser->running_avg_y[i].buffer_alloc != NULL)
445− copy_frame(&denoiser->running_avg_y[i], &src);
461+ if (denoiser->running_avg_y[i + shift].buffer_alloc != NULL)
462+ copy_frame(&denoiser->running_avg_y[i + shift], &src);
446463 }
447464 denoiser->reset = 0;
448465 return;
@@ -451,29 +468,29 @@ void vp9_denoiser_update_frame_info( · 2 unmodified lines
451468 // If more than one refresh occurs, must copy frame buffer.
452469 if ((refresh_alt_ref_frame + refresh_golden_frame + refresh_last_frame) > 1) {
453470 if (refresh_alt_ref_frame) {
454− copy_frame(&denoiser->running_avg_y[alt_fb_idx + 1],
455− &denoiser->running_avg_y[INTRA_FRAME]);
471+ copy_frame(&denoiser->running_avg_y[alt_fb_idx + 1 + shift],
472+ &denoiser->running_avg_y[INTRA_FRAME + shift]);
456473 }
457474 if (refresh_golden_frame) {
458− copy_frame(&denoiser->running_avg_y[gld_fb_idx + 1],
459− &denoiser->running_avg_y[INTRA_FRAME]);
475+ copy_frame(&denoiser->running_avg_y[gld_fb_idx + 1 + shift],
476+ &denoiser->running_avg_y[INTRA_FRAME + shift]);
460477 }
461478 if (refresh_last_frame) {
462− copy_frame(&denoiser->running_avg_y[lst_fb_idx + 1],
463− &denoiser->running_avg_y[INTRA_FRAME]);
479+ copy_frame(&denoiser->running_avg_y[lst_fb_idx + 1 + shift],
480+ &denoiser->running_avg_y[INTRA_FRAME + shift]);
464481 }
465482 } else {
466483 if (refresh_alt_ref_frame) {
467− swap_frame_buffer(&denoiser->running_avg_y[alt_fb_idx + 1],
468− &denoiser->running_avg_y[INTRA_FRAME]);
484+ swap_frame_buffer(&denoiser->running_avg_y[alt_fb_idx + 1 + shift],
485+ &denoiser->running_avg_y[INTRA_FRAME + shift]);
469486 }
470487 if (refresh_golden_frame) {
471− swap_frame_buffer(&denoiser->running_avg_y[gld_fb_idx + 1],
472− &denoiser->running_avg_y[INTRA_FRAME]);
488+ swap_frame_buffer(&denoiser->running_avg_y[gld_fb_idx + 1 + shift],
489+ &denoiser->running_avg_y[INTRA_FRAME + shift]);
473490 }
474491 if (refresh_last_frame) {
475− swap_frame_buffer(&denoiser->running_avg_y[lst_fb_idx + 1],
476− &denoiser->running_avg_y[INTRA_FRAME]);
492+ swap_frame_buffer(&denoiser->running_avg_y[lst_fb_idx + 1 + shift],
493+ &denoiser->running_avg_y[INTRA_FRAME + shift]);
477494 }
478495 }
479496 }
@@ -522,44 +539,90 @@ static int vp9_denoiser_realloc_svc_helper(VP9_COMMON *cm, · 42 unmodified lines
522539 }
523540
524541 int vp9_denoiser_realloc_svc(VP9_COMMON *cm, VP9_DENOISER *denoiser,
525− int refresh_alt, int refresh_gld, int refresh_lst,
526− int alt_fb_idx, int gld_fb_idx, int lst_fb_idx) {
542+ int svc_buf_shift, int refresh_alt,
543+ int refresh_gld, int refresh_lst, int alt_fb_idx,
544+ int gld_fb_idx, int lst_fb_idx) {
527545 int fail = 0;
528546 if (refresh_alt) {
529547 // Increase the frame buffer index by 1 to map it to the buffer index in the
530548 // denoiser.
531− fail = vp9_denoiser_realloc_svc_helper(cm, denoiser, alt_fb_idx + 1);
549+ fail = vp9_denoiser_realloc_svc_helper(cm, denoiser,
550+ alt_fb_idx + 1 + svc_buf_shift);
532551 if (fail) return 1;
533552 }
534553 if (refresh_gld) {
535− fail = vp9_denoiser_realloc_svc_helper(cm, denoiser, gld_fb_idx + 1);
554+ fail = vp9_denoiser_realloc_svc_helper(cm, denoiser,
555+ gld_fb_idx + 1 + svc_buf_shift);
536556 if (fail) return 1;
537557 }
538558 if (refresh_lst) {
539− fail = vp9_denoiser_realloc_svc_helper(cm, denoiser, lst_fb_idx + 1);
559+ fail = vp9_denoiser_realloc_svc_helper(cm, denoiser,
560+ lst_fb_idx + 1 + svc_buf_shift);
540561 if (fail) return 1;
541562 }
542563 return 0;
543564 }
544565
545−int vp9_denoiser_alloc(VP9_COMMON *cm, int use_svc, VP9_DENOISER *denoiser,
546− int width, int height, int ssx, int ssy,
566+int vp9_denoiser_alloc(VP9_COMMON *cm, struct SVC *svc, VP9_DENOISER *denoiser,
567+ int use_svc, int noise_sen, int width, int height,
568+ int ssx, int ssy,
547569 #if CONFIG_VP9_HIGHBITDEPTH
548570 int use_highbitdepth,
549571 #endif
550572 int border) {
551− int i, fail, init_num_ref_frames;
573+ int i, layer, fail, init_num_ref_frames;
552574 const int legacy_byte_alignment = 0;
575+ int num_layers = 1;
576+ int scaled_width = width;
577+ int scaled_height = height;
578+ if (use_svc) {
579+ LAYER_CONTEXT *lc = &svc->layer_context[svc->spatial_layer_id *
580+ svc->number_temporal_layers +
581+ svc->temporal_layer_id];
582+ get_layer_resolution(width, height, lc->scaling_factor_num,
583+ lc->scaling_factor_den, &scaled_width, &scaled_height);
584+ // For SVC: only denoise at most 2 spatial (highest) layers.
585+ if (noise_sen >= 2)
586+ // Denoise from one spatial layer below the top.
587+ svc->first_layer_denoise = VPXMAX(svc->number_spatial_layers - 2, 0);
588+ else
589+ // Only denoise the top spatial layer.
590+ svc->first_layer_denoise = VPXMAX(svc->number_spatial_layers - 1, 0);
591+ num_layers = svc->number_spatial_layers - svc->first_layer_denoise;
592+ }
553593 assert(denoiser != NULL);
554−
555594 denoiser->num_ref_frames = use_svc ? SVC_REF_FRAMES : NONSVC_REF_FRAMES;
556595 init_num_ref_frames = use_svc ? MAX_REF_FRAMES : NONSVC_REF_FRAMES;
596+ denoiser->num_layers = num_layers;
597+ CHECK_MEM_ERROR(cm, denoiser->running_avg_y,
598+ vpx_calloc(denoiser->num_ref_frames * num_layers,
599+ sizeof(denoiser->running_avg_y[0])));
557600 CHECK_MEM_ERROR(
558− cm, denoiser->running_avg_y,
559− vpx_calloc(denoiser->num_ref_frames, sizeof(denoiser->running_avg_y[0])));
560− for (i = 0; i < init_num_ref_frames; ++i) {
561− fail = vpx_alloc_frame_buffer(&denoiser->running_avg_y[i], width, height,
562− ssx, ssy,
601+ cm, denoiser->mc_running_avg_y,
602+ vpx_calloc(num_layers, sizeof(denoiser->mc_running_avg_y[0])));
603+
604+ for (layer = 0; layer < num_layers; ++layer) {
605+ const int denoise_width = (layer == 0) ? width : scaled_width;
606+ const int denoise_height = (layer == 0) ? height : scaled_height;
607+ for (i = 0; i < init_num_ref_frames; ++i) {
608+ fail = vpx_alloc_frame_buffer(
609+ &denoiser->running_avg_y[i + denoiser->num_ref_frames * layer],
610+ denoise_width, denoise_height, ssx, ssy,
611+#if CONFIG_VP9_HIGHBITDEPTH
612+ use_highbitdepth,
613+#endif
614+ border, legacy_byte_alignment);
615+ if (fail) {
616+ vp9_denoiser_free(denoiser);
617+ return 1;
618+ }
619+#ifdef OUTPUT_YUV_DENOISED
620+ make_grayscale(&denoiser->running_avg_y[i]);
621+#endif
622+ }
623+
624+ fail = vpx_alloc_frame_buffer(&denoiser->mc_running_avg_y[layer],
625+ denoise_width, denoise_height, ssx, ssy,
563626 #if CONFIG_VP9_HIGHBITDEPTH
564627 use_highbitdepth,
565628 #endif
@@ -568,22 +631,10 @@ int vp9_denoiser_alloc(VP9_COMMON *cm, int use_svc, VP9_DENOISER *denoiser, · 2 unmodified lines
568631 vp9_denoiser_free(denoiser);
569632 return 1;
570633 }
571−#ifdef OUTPUT_YUV_DENOISED
572− make_grayscale(&denoiser->running_avg_y[i]);
573−#endif
574− }
575−
576− fail = vpx_alloc_frame_buffer(&denoiser->mc_running_avg_y, width, height, ssx,
577− ssy,
578−#if CONFIG_VP9_HIGHBITDEPTH
579− use_highbitdepth,
580−#endif
581− border, legacy_byte_alignment);
582− if (fail) {
583− vp9_denoiser_free(denoiser);
584− return 1;
585634 }
586635
636+ // denoiser->last_source only used for noise_estimation, so only for top
637+ // layer.
587638 fail = vpx_alloc_frame_buffer(&denoiser->last_source, width, height, ssx, ssy,
588639 #if CONFIG_VP9_HIGHBITDEPTH
589640 use_highbitdepth,
@@ -609,12 +660,18 @@ void vp9_denoiser_free(VP9_DENOISER *denoiser) { · 19 unmodified lines
609660 return;
610661 }
611662 denoiser->frame_buffer_initialized = 0;
612− for (i = 0; i < denoiser->num_ref_frames; ++i) {
663+ for (i = 0; i < denoiser->num_ref_frames * denoiser->num_layers; ++i) {
613664 vpx_free_frame_buffer(&denoiser->running_avg_y[i]);
614665 }
615666 vpx_free(denoiser->running_avg_y);
616667 denoiser->running_avg_y = NULL;
617− vpx_free_frame_buffer(&denoiser->mc_running_avg_y);
668+
669+ for (i = 0; i < denoiser->num_layers; ++i) {
670+ vpx_free_frame_buffer(&denoiser->mc_running_avg_y[i]);
671+ }
672+
673+ vpx_free(denoiser->mc_running_avg_y);
674+ denoiser->mc_running_avg_y = NULL;
618675 vpx_free_frame_buffer(&denoiser->last_source);
619676 }
620677
vp9/encoder/vp9_denoiser.h+10−6
@@ -44,11 +44,12 @@ typedef enum vp9_denoiser_level { · 43 unmodified lines
4444
4545 typedef struct vp9_denoiser {
4646 YV12_BUFFER_CONFIG *running_avg_y;
47− YV12_BUFFER_CONFIG mc_running_avg_y;
47+ YV12_BUFFER_CONFIG *mc_running_avg_y;
4848 YV12_BUFFER_CONFIG last_source;
4949 int frame_buffer_initialized;
5050 int reset;
5151 int num_ref_frames;
52+ int num_layers;
5253 VP9_DENOISER_LEVEL denoising_level;
5354 VP9_DENOISER_LEVEL prev_denoising_level;
5455 } VP9_DENOISER;
@@ -66,12 +67,13 @@ typedef struct { · 11 unmodified lines
6667 } VP9_PICKMODE_CTX_DEN;
6768
6869 struct VP9_COMP;
70+struct SVC;
6971
7072 void vp9_denoiser_update_frame_info(
7173 VP9_DENOISER *denoiser, YV12_BUFFER_CONFIG src, FRAME_TYPE frame_type,
7274 int refresh_alt_ref_frame, int refresh_golden_frame, int refresh_last_frame,
7375 int alt_fb_idx, int gld_fb_idx, int lst_fb_idx, int resized,
74− int svc_base_is_key);
76+ int svc_base_is_key, int second_spatial_layer);
7577
7678 void vp9_denoiser_denoise(struct VP9_COMP *cpi, MACROBLOCK *mb, int mi_row,
7779 int mi_col, BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx,
@@ -84,11 +86,13 @@ void vp9_denoiser_update_frame_stats(MODE_INFO *mi, unsigned int sse, · 6 unmodified lines
8486 PICK_MODE_CONTEXT *ctx);
8587
8688 int vp9_denoiser_realloc_svc(VP9_COMMON *cm, VP9_DENOISER *denoiser,
87− int refresh_alt, int refresh_gld, int refresh_lst,
88− int alt_fb_idx, int gld_fb_idx, int lst_fb_idx);
89+ int svc_buf_shift, int refresh_alt,
90+ int refresh_gld, int refresh_lst, int alt_fb_idx,
91+ int gld_fb_idx, int lst_fb_idx);
8992
90−int vp9_denoiser_alloc(VP9_COMMON *cm, int use_svc, VP9_DENOISER *denoiser,
91− int width, int height, int ssx, int ssy,
93+int vp9_denoiser_alloc(VP9_COMMON *cm, struct SVC *svc, VP9_DENOISER *denoiser,
94+ int use_svc, int noise_sen, int width, int height,
95+ int ssx, int ssy,
9296 #if CONFIG_VP9_HIGHBITDEPTH
9397 int use_highbitdepth,
9498 #endif
vp9/encoder/vp9_encoder.c+16−6
@@ -2861,18 +2861,26 @@ void vp9_update_reference_frames(VP9_COMP *cpi) { · 2860 unmodified lines
28612861 if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi) &&
28622862 cpi->denoiser.denoising_level > kDenLowLow) {
28632863 int svc_base_is_key = 0;
2864+ int denoise_svc_second_layer = 0;
28642865 if (cpi->use_svc) {
28652866 int realloc_fail = 0;
2867+ const int svc_buf_shift =
2868+ cpi->svc.number_spatial_layers - cpi->svc.spatial_layer_id == 2
2869+ ? cpi->denoiser.num_ref_frames
2870+ : 0;
28662871 int layer = LAYER_IDS_TO_IDX(cpi->svc.spatial_layer_id,
28672872 cpi->svc.temporal_layer_id,
28682873 cpi->svc.number_temporal_layers);
28692874 LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer];
28702875 svc_base_is_key = lc->is_key_frame;
2871−
2872− // Check if we need to allocate extra buffers in the denoiser for
2876+ denoise_svc_second_layer =
2877+ cpi->svc.number_spatial_layers - cpi->svc.spatial_layer_id == 2 ? 1
2878+ : 0;
2879+ // Check if we need to allocate extra buffers in the denoiser
2880+ // for
28732881 // refreshed frames.
28742882 realloc_fail = vp9_denoiser_realloc_svc(
2875− cm, &cpi->denoiser, cpi->refresh_alt_ref_frame,
2883+ cm, &cpi->denoiser, svc_buf_shift, cpi->refresh_alt_ref_frame,
28762884 cpi->refresh_golden_frame, cpi->refresh_last_frame, cpi->alt_fb_idx,
28772885 cpi->gld_fb_idx, cpi->lst_fb_idx);
28782886 if (realloc_fail)
@@ -2883,7 +2891,8 @@ void vp9_update_reference_frames(VP9_COMP *cpi) { · 4 unmodified lines
28832891 &cpi->denoiser, *cpi->Source, cpi->common.frame_type,
28842892 cpi->refresh_alt_ref_frame, cpi->refresh_golden_frame,
28852893 cpi->refresh_last_frame, cpi->alt_fb_idx, cpi->gld_fb_idx,
2886− cpi->lst_fb_idx, cpi->resize_pending, svc_base_is_key);
2894+ cpi->lst_fb_idx, cpi->resize_pending, svc_base_is_key,
2895+ denoise_svc_second_layer);
28872896 }
28882897 #endif
28892898 if (is_one_pass_cbr_svc(cpi)) {
@@ -3318,8 +3327,9 @@ static void setup_denoiser_buffer(VP9_COMP *cpi) { · 428 unmodified lines
33183327 VP9_COMMON *const cm = &cpi->common;
33193328 if (cpi->oxcf.noise_sensitivity > 0 &&
33203329 !cpi->denoiser.frame_buffer_initialized) {
3321− if (vp9_denoiser_alloc(cm, cpi->use_svc, &cpi->denoiser, cm->width,
3322− cm->height, cm->subsampling_x, cm->subsampling_y,
3330+ if (vp9_denoiser_alloc(cm, &cpi->svc, &cpi->denoiser, cpi->use_svc,
3331+ cpi->oxcf.noise_sensitivity, cm->width, cm->height,
3332+ cm->subsampling_x, cm->subsampling_y,
33233333 #if CONFIG_VP9_HIGHBITDEPTH
33243334 cm->use_highbitdepth,
33253335 #endif
vp9/encoder/vp9_encoder.h+1−1
@@ -870,7 +870,7 @@ static INLINE int is_one_pass_cbr_svc(const struct VP9_COMP *const cpi) { · 869 unmodified lines
870870 static INLINE int denoise_svc(const struct VP9_COMP *const cpi) {
871871 return (!cpi->use_svc ||
872872 (cpi->use_svc &&
873− cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1));
873+ cpi->svc.spatial_layer_id >= cpi->svc.first_layer_denoise));
874874 }
875875 #endif
876876
vp9/encoder/vp9_noise_estimate.c+15−6
@@ -21,6 +21,15 @@ · 20 unmodified lines
2121 #include "vp9/encoder/vp9_noise_estimate.h"
2222 #include "vp9/encoder/vp9_encoder.h"
2323
24+#if CONFIG_VP9_TEMPORAL_DENOISING
25+// For SVC: only do noise estimation on top spatial layer.
26+static INLINE int noise_est_svc(const struct VP9_COMP *const cpi) {
27+ return (!cpi->use_svc ||
28+ (cpi->use_svc &&
29+ cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1));
30+}
31+#endif
32+
2433 void vp9_noise_estimate_init(NOISE_ESTIMATE *const ne, int width, int height) {
2534 ne->enabled = 0;
2635 ne->level = kLowLow;
@@ -45,7 +54,7 @@ static int enable_noise_estimation(VP9_COMP *const cpi) { · 18 unmodified lines
4554 #endif
4655 // Enable noise estimation if denoising is on.
4756 #if CONFIG_VP9_TEMPORAL_DENOISING
48− if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi) &&
57+ if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi) &&
4958 cpi->common.width >= 320 && cpi->common.height >= 180)
5059 return 1;
5160 #endif
@@ -111,7 +120,7 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) { · 59 unmodified lines
111120 // Estimate is between current source and last source.
112121 YV12_BUFFER_CONFIG *last_source = cpi->Last_Source;
113122 #if CONFIG_VP9_TEMPORAL_DENOISING
114− if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi)) {
123+ if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi)) {
115124 last_source = &cpi->denoiser.last_source;
116125 // Tune these thresholds for different resolutions when denoising is
117126 // enabled.
@@ -131,7 +140,7 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) { · 13 unmodified lines
131140 (cpi->svc.number_spatial_layers == 1 &&
132141 (ne->last_w != cm->width || ne->last_h != cm->height))) {
133142 #if CONFIG_VP9_TEMPORAL_DENOISING
134− if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi))
143+ if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi))
135144 copy_frame(&cpi->denoiser.last_source, cpi->Source);
136145 #endif
137146 if (last_source != NULL) {
@@ -146,7 +155,7 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) { · 8 unmodified lines
146155 ne->count = 0;
147156 ne->num_frames_estimate = 10;
148157 #if CONFIG_VP9_TEMPORAL_DENOISING
149− if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi) &&
158+ if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi) &&
150159 cpi->svc.current_superframe > 1) {
151160 vp9_denoiser_set_noise_level(&cpi->denoiser, ne->level);
152161 copy_frame(&cpi->denoiser.last_source, cpi->Source);
@@ -257,14 +266,14 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) { · 104 unmodified lines
257266 ne->count = 0;
258267 ne->level = vp9_noise_estimate_extract_level(ne);
259268 #if CONFIG_VP9_TEMPORAL_DENOISING
260− if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi))
269+ if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi))
261270 vp9_denoiser_set_noise_level(&cpi->denoiser, ne->level);
262271 #endif
263272 }
264273 }
265274 }
266275 #if CONFIG_VP9_TEMPORAL_DENOISING
267− if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi))
276+ if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi))
268277 copy_frame(&cpi->denoiser.last_source, cpi->Source);
269278 #endif
270279 }
vp9/encoder/vp9_svc_layercontext.c+4−3
@@ -37,6 +37,7 @@ void vp9_init_layer_context(VP9_COMP *const cpi) { · 36 unmodified lines
3737 svc->scaled_one_half = 0;
3838 svc->current_superframe = 0;
3939 svc->non_reference_frame = 0;
40+
4041 for (i = 0; i < REF_FRAMES; ++i) svc->ref_frame_index[i] = -1;
4142 for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
4243 svc->ext_frame_flags[sl] = 0;
@@ -389,9 +390,9 @@ int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) { · 346 unmodified lines
389390 .is_key_frame;
390391 }
391392
392−static void get_layer_resolution(const int width_org, const int height_org,
393− const int num, const int den, int *width_out,
394− int *height_out) {
393+void get_layer_resolution(const int width_org, const int height_org,
394+ const int num, const int den, int *width_out,
395+ int *height_out) {
395396 int w, h;
396397
397398 if (width_out == NULL || height_out == NULL || den == 0) return;
vp9/encoder/vp9_svc_layercontext.h+7−1
@@ -49,7 +49,7 @@ typedef struct { · 48 unmodified lines
4949 uint8_t speed;
5050 } LAYER_CONTEXT;
5151
52−typedef struct {
52+typedef struct SVC {
5353 int spatial_layer_id;
5454 int temporal_layer_id;
5555 int number_spatial_layers;
@@ -99,6 +99,8 @@ typedef struct { · 43 unmodified lines
9999
100100 BLOCK_SIZE *prev_partition_svc;
101101 int mi_stride[VPX_MAX_LAYERS];
102+
103+ int first_layer_denoise;
102104 } SVC;
103105
104106 struct VP9_COMP;
@@ -128,6 +130,10 @@ void vp9_save_layer_context(struct VP9_COMP *const cpi); · 23 unmodified lines
128130 // Initialize second pass rc for spatial svc.
129131 void vp9_init_second_pass_spatial_svc(struct VP9_COMP *cpi);
130132
133+void get_layer_resolution(const int width_org, const int height_org,
134+ const int num, const int den, int *width_out,
135+ int *height_out);
136+
131137 // Increment number of video frames in layer
132138 void vp9_inc_frame_in_layer(struct VP9_COMP *const cpi);
133139
vpx/vp8cx.h+1−1
@@ -408,7 +408,7 @@ enum vp8e_enc_control_id { · 407 unmodified lines
408408
409409 /*!\brief Codec control function to set noise sensitivity.
410410 *
411− * 0: off, 1: On(YOnly)
411+ * 0: off, 1: On(YOnly), 2: For SVC only, on top two spatial layers(YOnly)
412412 *
413413 * Supported in codecs: VP9
414414 */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t