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
32 32
33void usage_exit(void) { exit(EXIT_FAILURE); }33void usage_exit(void) { exit(EXIT_FAILURE); }
34 34
35// Denoiser states, for temporal denoising.35// Denoiser states for vp8, for temporal denoising.
36enum denoiserState {36enum denoiserStateVp8 {
37 kDenoiserOff,37 kVp8DenoiserOff,
38 kDenoiserOnYOnly,38 kVp8DenoiserOnYOnly,
39 kDenoiserOnYUV,39 kVp8DenoiserOnYUV,
40 kDenoiserOnYUVAggressive,40 kVp8DenoiserOnYUVAggressive,
41 kDenoiserOnAdaptive41 kVp8DenoiserOnAdaptive
42};
43
44// Denoiser states for vp9, for temporal denoising.
45enum denoiserStateVp9 {
46 kVp9DenoiserOff,
47 kVp9DenoiserOnYOnly,
48 // For SVC: denoise the top two spatial layers.
49 kVp9DenoiserOnYTwoSpatialLayers
42};50};
43 51
44static int mode_to_num_layers[13] = { 1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3 };52static 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
755 763
756 if (strncmp(encoder->name, "vp8", 3) == 0) {764 if (strncmp(encoder->name, "vp8", 3) == 0) {
757 vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);765 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);
759 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);767 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
760 vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);768 vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
761#if VP8_ROI_MAP769#if VP8_ROI_MAP
@@ -772,7 +780,7 @@ int main(int argc, char **argv) { · 10 unmodified lines
772 vpx_codec_control(&codec, VP9E_SET_GF_CBR_BOOST_PCT, 0);780 vpx_codec_control(&codec, VP9E_SET_GF_CBR_BOOST_PCT, 0);
773 vpx_codec_control(&codec, VP9E_SET_FRAME_PARALLEL_DECODING, 0);781 vpx_codec_control(&codec, VP9E_SET_FRAME_PARALLEL_DECODING, 0);
774 vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);782 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);
776 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);784 vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
777 vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);785 vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
778 vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));786 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
1449 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);1449 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1450 // TODO(marpan): Check that effective_datarate for each layer hits the1450 // TODO(marpan): Check that effective_datarate for each layer hits the
1451 // layer target_bitrate.1451 // layer target_bitrate.
1452 for (int i = 600; i <= 1000; i += 200) {1452 // For SVC, noise_sen = 1 means denoising only the top spatial layer
1453 cfg_.rc_target_bitrate = i;1453 // noise_sen = 2 means denoising the two top spatial layers.
1454 ResetModel();1454 for (int noise_sen = 1; noise_sen <= 2; noise_sen++) {
1455 denoiser_on_ = 1;1455 for (int i = 600; i <= 1000; i += 200) {
1456 assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,1456 cfg_.rc_target_bitrate = i;
1457 cfg_.ts_number_layers, cfg_.temporal_layering_mode);1457 ResetModel();
1458 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));1458 denoiser_on_ = noise_sen;
1459 ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)1459 assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1460 << " The datarate for the file exceeds the target by too much!";1460 cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1461 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)1461 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1462 << " The datarate for the file is lower than the target by too much!";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!";
1463#if CONFIG_VP9_DECODER1466#if CONFIG_VP9_DECODER
1464 // Number of temporal layers > 1, so half of the frames in this SVC pattern1467 // Number of temporal layers > 1, so half of the frames in this SVC
1465 // will be non-reference frame and hence encoder will avoid loopfilter.1468 // pattern
1466 // Since frame dropper is off, we can expcet 150 (half of the sequence)1469 // will be non-reference frame and hence encoder will avoid loopfilter.
1467 // mismatched frames.1470 // Since frame dropper is off, we can expcet 150 (half of the sequence)
1468 EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());1471 // mismatched frames.
1472 EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
1469#endif1473#endif
1474 }
1470 }1475 }
1471}1476}
1472 1477
vp9/encoder/vp9_denoiser.c+118−61
@@ -189,11 +189,12 @@ static VP9_DENOISER_DECISION perform_motion_compensation( · 188 unmodified lines
189 int increase_denoising, int mi_row, int mi_col, PICK_MODE_CONTEXT *ctx,189 int increase_denoising, int mi_row, int mi_col, PICK_MODE_CONTEXT *ctx,
190 int motion_magnitude, int is_skin, int *zeromv_filter, int consec_zeromv,190 int motion_magnitude, int is_skin, int *zeromv_filter, int consec_zeromv,
191 int num_spatial_layers, int width, int lst_fb_idx, int gld_fb_idx,191 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) {
193 const int sse_diff = (ctx->newmv_sse == UINT_MAX)193 const int sse_diff = (ctx->newmv_sse == UINT_MAX)
194 ? 0194 ? 0
195 : ((int)ctx->zeromv_sse - (int)ctx->newmv_sse);195 : ((int)ctx->zeromv_sse - (int)ctx->newmv_sse);
196 int frame;196 int frame;
197 int denoise_layer_idx = 0;
197 MACROBLOCKD *filter_mbd = &mb->e_mbd;198 MACROBLOCKD *filter_mbd = &mb->e_mbd;
198 MODE_INFO *mi = filter_mbd->mi[0];199 MODE_INFO *mi = filter_mbd->mi[0];
199 MODE_INFO saved_mi;200 MODE_INFO saved_mi;
@@ -254,6 +255,10 @@ static VP9_DENOISER_DECISION perform_motion_compensation( · 54 unmodified lines
254 frame = lst_fb_idx + 1;255 frame = lst_fb_idx + 1;
255 else if (frame == GOLDEN_FRAME)256 else if (frame == GOLDEN_FRAME)
256 frame = gld_fb_idx + 1;257 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;
257 }262 }
258 263
259 if (ctx->newmv_sse > sse_thresh(bs, increase_denoising)) {264 if (ctx->newmv_sse > sse_thresh(bs, increase_denoising)) {
@@ -289,18 +294,21 @@ static VP9_DENOISER_DECISION perform_motion_compensation( · 29 unmodified lines
289 denoiser->running_avg_y[frame].uv_stride, mi_row, mi_col);294 denoiser->running_avg_y[frame].uv_stride, mi_row, mi_col);
290 filter_mbd->plane[2].pre[0].stride = denoiser->running_avg_y[frame].uv_stride;295 filter_mbd->plane[2].pre[0].stride = denoiser->running_avg_y[frame].uv_stride;
291 296
292 filter_mbd->plane[0].dst.buf =297 filter_mbd->plane[0].dst.buf = block_start(
293 block_start(denoiser->mc_running_avg_y.y_buffer,298 denoiser->mc_running_avg_y[denoise_layer_idx].y_buffer,
294 denoiser->mc_running_avg_y.y_stride, mi_row, mi_col);299 denoiser->mc_running_avg_y[denoise_layer_idx].y_stride, mi_row, mi_col);
295 filter_mbd->plane[0].dst.stride = denoiser->mc_running_avg_y.y_stride;300 filter_mbd->plane[0].dst.stride =
296 filter_mbd->plane[1].dst.buf =301 denoiser->mc_running_avg_y[denoise_layer_idx].y_stride;
297 block_start(denoiser->mc_running_avg_y.u_buffer,302 filter_mbd->plane[1].dst.buf = block_start(
298 denoiser->mc_running_avg_y.uv_stride, mi_row, mi_col);303 denoiser->mc_running_avg_y[denoise_layer_idx].u_buffer,
299 filter_mbd->plane[1].dst.stride = denoiser->mc_running_avg_y.uv_stride;304 denoiser->mc_running_avg_y[denoise_layer_idx].uv_stride, mi_row, mi_col);
300 filter_mbd->plane[2].dst.buf =305 filter_mbd->plane[1].dst.stride =
301 block_start(denoiser->mc_running_avg_y.v_buffer,306 denoiser->mc_running_avg_y[denoise_layer_idx].uv_stride;
302 denoiser->mc_running_avg_y.uv_stride, mi_row, mi_col);307 filter_mbd->plane[2].dst.buf = block_start(
303 filter_mbd->plane[2].dst.stride = denoiser->mc_running_avg_y.uv_stride;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;
304 312
305 set_ref_ptrs(cm, filter_mbd, saved_frame, NONE);313 set_ref_ptrs(cm, filter_mbd, saved_frame, NONE);
306 vp9_build_inter_predictors_sby(filter_mbd, mi_row, mi_col, bs);314 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
324 int zeromv_filter = 0;332 int zeromv_filter = 0;
325 VP9_DENOISER *denoiser = &cpi->denoiser;333 VP9_DENOISER *denoiser = &cpi->denoiser;
326 VP9_DENOISER_DECISION decision = COPY_BLOCK;334 VP9_DENOISER_DECISION decision = COPY_BLOCK;
327 YV12_BUFFER_CONFIG avg = denoiser->running_avg_y[INTRA_FRAME];335
328 YV12_BUFFER_CONFIG mc_avg = denoiser->mc_running_avg_y;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];
329 uint8_t *avg_start = block_start(avg.y_buffer, avg.y_stride, mi_row, mi_col);344 uint8_t *avg_start = block_start(avg.y_buffer, avg.y_stride, mi_row, mi_col);
345
330 uint8_t *mc_avg_start =346 uint8_t *mc_avg_start =
331 block_start(mc_avg.y_buffer, mc_avg.y_stride, mi_row, mi_col);347 block_start(mc_avg.y_buffer, mc_avg.y_stride, mi_row, mi_col);
332 struct buf_2d src = mb->plane[0].src;348 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
381 &cpi->common, denoiser, mb, bs, increase_denoising, mi_row, mi_col, ctx,397 &cpi->common, denoiser, mb, bs, increase_denoising, mi_row, mi_col, ctx,
382 motion_magnitude, is_skin, &zeromv_filter, consec_zeromv,398 motion_magnitude, is_skin, &zeromv_filter, consec_zeromv,
383 cpi->svc.number_spatial_layers, cpi->Source->y_width, cpi->lst_fb_idx,399 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);
385 401
386 if (decision == FILTER_BLOCK) {402 if (decision == FILTER_BLOCK) {
387 decision = vp9_denoiser_filter(src.buf, src.stride, mc_avg_start,403 decision = vp9_denoiser_filter(src.buf, src.stride, mc_avg_start,
@@ -432,7 +448,8 @@ void vp9_denoiser_update_frame_info( · 44 unmodified lines
432 VP9_DENOISER *denoiser, YV12_BUFFER_CONFIG src, FRAME_TYPE frame_type,448 VP9_DENOISER *denoiser, YV12_BUFFER_CONFIG src, FRAME_TYPE frame_type,
433 int refresh_alt_ref_frame, int refresh_golden_frame, int refresh_last_frame,449 int refresh_alt_ref_frame, int refresh_golden_frame, int refresh_last_frame,
434 int alt_fb_idx, int gld_fb_idx, int lst_fb_idx, int resized,450 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;
436 // Copy source into denoised reference buffers on KEY_FRAME or453 // Copy source into denoised reference buffers on KEY_FRAME or
437 // if the just encoded frame was resized. For SVC, copy source if the base454 // if the just encoded frame was resized. For SVC, copy source if the base
438 // spatial layer was key frame.455 // spatial layer was key frame.
@@ -441,8 +458,8 @@ void vp9_denoiser_update_frame_info( · 2 unmodified lines
441 int i;458 int i;
442 // Start at 1 so as not to overwrite the INTRA_FRAME459 // Start at 1 so as not to overwrite the INTRA_FRAME
443 for (i = 1; i < denoiser->num_ref_frames; ++i) {460 for (i = 1; i < denoiser->num_ref_frames; ++i) {
444 if (denoiser->running_avg_y[i].buffer_alloc != NULL)461 if (denoiser->running_avg_y[i + shift].buffer_alloc != NULL)
445 copy_frame(&denoiser->running_avg_y[i], &src);462 copy_frame(&denoiser->running_avg_y[i + shift], &src);
446 }463 }
447 denoiser->reset = 0;464 denoiser->reset = 0;
448 return;465 return;
@@ -451,29 +468,29 @@ void vp9_denoiser_update_frame_info( · 2 unmodified lines
451 // If more than one refresh occurs, must copy frame buffer.468 // If more than one refresh occurs, must copy frame buffer.
452 if ((refresh_alt_ref_frame + refresh_golden_frame + refresh_last_frame) > 1) {469 if ((refresh_alt_ref_frame + refresh_golden_frame + refresh_last_frame) > 1) {
453 if (refresh_alt_ref_frame) {470 if (refresh_alt_ref_frame) {
454 copy_frame(&denoiser->running_avg_y[alt_fb_idx + 1],471 copy_frame(&denoiser->running_avg_y[alt_fb_idx + 1 + shift],
455 &denoiser->running_avg_y[INTRA_FRAME]);472 &denoiser->running_avg_y[INTRA_FRAME + shift]);
456 }473 }
457 if (refresh_golden_frame) {474 if (refresh_golden_frame) {
458 copy_frame(&denoiser->running_avg_y[gld_fb_idx + 1],475 copy_frame(&denoiser->running_avg_y[gld_fb_idx + 1 + shift],
459 &denoiser->running_avg_y[INTRA_FRAME]);476 &denoiser->running_avg_y[INTRA_FRAME + shift]);
460 }477 }
461 if (refresh_last_frame) {478 if (refresh_last_frame) {
462 copy_frame(&denoiser->running_avg_y[lst_fb_idx + 1],479 copy_frame(&denoiser->running_avg_y[lst_fb_idx + 1 + shift],
463 &denoiser->running_avg_y[INTRA_FRAME]);480 &denoiser->running_avg_y[INTRA_FRAME + shift]);
464 }481 }
465 } else {482 } else {
466 if (refresh_alt_ref_frame) {483 if (refresh_alt_ref_frame) {
467 swap_frame_buffer(&denoiser->running_avg_y[alt_fb_idx + 1],484 swap_frame_buffer(&denoiser->running_avg_y[alt_fb_idx + 1 + shift],
468 &denoiser->running_avg_y[INTRA_FRAME]);485 &denoiser->running_avg_y[INTRA_FRAME + shift]);
469 }486 }
470 if (refresh_golden_frame) {487 if (refresh_golden_frame) {
471 swap_frame_buffer(&denoiser->running_avg_y[gld_fb_idx + 1],488 swap_frame_buffer(&denoiser->running_avg_y[gld_fb_idx + 1 + shift],
472 &denoiser->running_avg_y[INTRA_FRAME]);489 &denoiser->running_avg_y[INTRA_FRAME + shift]);
473 }490 }
474 if (refresh_last_frame) {491 if (refresh_last_frame) {
475 swap_frame_buffer(&denoiser->running_avg_y[lst_fb_idx + 1],492 swap_frame_buffer(&denoiser->running_avg_y[lst_fb_idx + 1 + shift],
476 &denoiser->running_avg_y[INTRA_FRAME]);493 &denoiser->running_avg_y[INTRA_FRAME + shift]);
477 }494 }
478 }495 }
479}496}
@@ -522,44 +539,90 @@ static int vp9_denoiser_realloc_svc_helper(VP9_COMMON *cm, · 42 unmodified lines
522}539}
523 540
524int vp9_denoiser_realloc_svc(VP9_COMMON *cm, VP9_DENOISER *denoiser,541int vp9_denoiser_realloc_svc(VP9_COMMON *cm, VP9_DENOISER *denoiser,
525 int refresh_alt, int refresh_gld, int refresh_lst,542 int svc_buf_shift, int refresh_alt,
526 int alt_fb_idx, int gld_fb_idx, int lst_fb_idx) {543 int refresh_gld, int refresh_lst, int alt_fb_idx,
544 int gld_fb_idx, int lst_fb_idx) {
527 int fail = 0;545 int fail = 0;
528 if (refresh_alt) {546 if (refresh_alt) {
529 // Increase the frame buffer index by 1 to map it to the buffer index in the547 // Increase the frame buffer index by 1 to map it to the buffer index in the
530 // denoiser.548 // 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);
532 if (fail) return 1;551 if (fail) return 1;
533 }552 }
534 if (refresh_gld) {553 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);
536 if (fail) return 1;556 if (fail) return 1;
537 }557 }
538 if (refresh_lst) {558 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);
540 if (fail) return 1;561 if (fail) return 1;
541 }562 }
542 return 0;563 return 0;
543}564}
544 565
545int vp9_denoiser_alloc(VP9_COMMON *cm, int use_svc, VP9_DENOISER *denoiser,566int vp9_denoiser_alloc(VP9_COMMON *cm, struct SVC *svc, VP9_DENOISER *denoiser,
546 int width, int height, int ssx, int ssy,567 int use_svc, int noise_sen, int width, int height,
568 int ssx, int ssy,
547#if CONFIG_VP9_HIGHBITDEPTH569#if CONFIG_VP9_HIGHBITDEPTH
548 int use_highbitdepth,570 int use_highbitdepth,
549#endif571#endif
550 int border) {572 int border) {
551 int i, fail, init_num_ref_frames;573 int i, layer, fail, init_num_ref_frames;
552 const int legacy_byte_alignment = 0;574 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 }
553 assert(denoiser != NULL);593 assert(denoiser != NULL);
554
555 denoiser->num_ref_frames = use_svc ? SVC_REF_FRAMES : NONSVC_REF_FRAMES;594 denoiser->num_ref_frames = use_svc ? SVC_REF_FRAMES : NONSVC_REF_FRAMES;
556 init_num_ref_frames = use_svc ? MAX_REF_FRAMES : NONSVC_REF_FRAMES;595 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])));
557 CHECK_MEM_ERROR(600 CHECK_MEM_ERROR(
558 cm, denoiser->running_avg_y,601 cm, denoiser->mc_running_avg_y,
559 vpx_calloc(denoiser->num_ref_frames, sizeof(denoiser->running_avg_y[0])));602 vpx_calloc(num_layers, sizeof(denoiser->mc_running_avg_y[0])));
560 for (i = 0; i < init_num_ref_frames; ++i) {603
561 fail = vpx_alloc_frame_buffer(&denoiser->running_avg_y[i], width, height,604 for (layer = 0; layer < num_layers; ++layer) {
562 ssx, ssy,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,
563#if CONFIG_VP9_HIGHBITDEPTH626#if CONFIG_VP9_HIGHBITDEPTH
564 use_highbitdepth,627 use_highbitdepth,
565#endif628#endif
@@ -568,22 +631,10 @@ int vp9_denoiser_alloc(VP9_COMMON *cm, int use_svc, VP9_DENOISER *denoiser, · 2 unmodified lines
568 vp9_denoiser_free(denoiser);631 vp9_denoiser_free(denoiser);
569 return 1;632 return 1;
570 }633 }
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;
585 }634 }
586 635
636 // denoiser->last_source only used for noise_estimation, so only for top
637 // layer.
587 fail = vpx_alloc_frame_buffer(&denoiser->last_source, width, height, ssx, ssy,638 fail = vpx_alloc_frame_buffer(&denoiser->last_source, width, height, ssx, ssy,
588#if CONFIG_VP9_HIGHBITDEPTH639#if CONFIG_VP9_HIGHBITDEPTH
589 use_highbitdepth,640 use_highbitdepth,
@@ -609,12 +660,18 @@ void vp9_denoiser_free(VP9_DENOISER *denoiser) { · 19 unmodified lines
609 return;660 return;
610 }661 }
611 denoiser->frame_buffer_initialized = 0;662 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) {
613 vpx_free_frame_buffer(&denoiser->running_avg_y[i]);664 vpx_free_frame_buffer(&denoiser->running_avg_y[i]);
614 }665 }
615 vpx_free(denoiser->running_avg_y);666 vpx_free(denoiser->running_avg_y);
616 denoiser->running_avg_y = NULL;667 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;
618 vpx_free_frame_buffer(&denoiser->last_source);675 vpx_free_frame_buffer(&denoiser->last_source);
619}676}
620 677
vp9/encoder/vp9_denoiser.h+10−6
@@ -44,11 +44,12 @@ typedef enum vp9_denoiser_level { · 43 unmodified lines
44 44
45typedef struct vp9_denoiser {45typedef struct vp9_denoiser {
46 YV12_BUFFER_CONFIG *running_avg_y;46 YV12_BUFFER_CONFIG *running_avg_y;
47 YV12_BUFFER_CONFIG mc_running_avg_y;47 YV12_BUFFER_CONFIG *mc_running_avg_y;
48 YV12_BUFFER_CONFIG last_source;48 YV12_BUFFER_CONFIG last_source;
49 int frame_buffer_initialized;49 int frame_buffer_initialized;
50 int reset;50 int reset;
51 int num_ref_frames;51 int num_ref_frames;
52 int num_layers;
52 VP9_DENOISER_LEVEL denoising_level;53 VP9_DENOISER_LEVEL denoising_level;
53 VP9_DENOISER_LEVEL prev_denoising_level;54 VP9_DENOISER_LEVEL prev_denoising_level;
54} VP9_DENOISER;55} VP9_DENOISER;
@@ -66,12 +67,13 @@ typedef struct { · 11 unmodified lines
66} VP9_PICKMODE_CTX_DEN;67} VP9_PICKMODE_CTX_DEN;
67 68
68struct VP9_COMP;69struct VP9_COMP;
70struct SVC;
69 71
70void vp9_denoiser_update_frame_info(72void vp9_denoiser_update_frame_info(
71 VP9_DENOISER *denoiser, YV12_BUFFER_CONFIG src, FRAME_TYPE frame_type,73 VP9_DENOISER *denoiser, YV12_BUFFER_CONFIG src, FRAME_TYPE frame_type,
72 int refresh_alt_ref_frame, int refresh_golden_frame, int refresh_last_frame,74 int refresh_alt_ref_frame, int refresh_golden_frame, int refresh_last_frame,
73 int alt_fb_idx, int gld_fb_idx, int lst_fb_idx, int resized,75 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);
75 77
76void vp9_denoiser_denoise(struct VP9_COMP *cpi, MACROBLOCK *mb, int mi_row,78void vp9_denoiser_denoise(struct VP9_COMP *cpi, MACROBLOCK *mb, int mi_row,
77 int mi_col, BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx,79 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
84 PICK_MODE_CONTEXT *ctx);86 PICK_MODE_CONTEXT *ctx);
85 87
86int vp9_denoiser_realloc_svc(VP9_COMMON *cm, VP9_DENOISER *denoiser,88int vp9_denoiser_realloc_svc(VP9_COMMON *cm, VP9_DENOISER *denoiser,
87 int refresh_alt, int refresh_gld, int refresh_lst,89 int svc_buf_shift, int refresh_alt,
88 int alt_fb_idx, int gld_fb_idx, int lst_fb_idx);90 int refresh_gld, int refresh_lst, int alt_fb_idx,
91 int gld_fb_idx, int lst_fb_idx);
89 92
90int vp9_denoiser_alloc(VP9_COMMON *cm, int use_svc, VP9_DENOISER *denoiser,93int vp9_denoiser_alloc(VP9_COMMON *cm, struct SVC *svc, VP9_DENOISER *denoiser,
91 int width, int height, int ssx, int ssy,94 int use_svc, int noise_sen, int width, int height,
95 int ssx, int ssy,
92#if CONFIG_VP9_HIGHBITDEPTH96#if CONFIG_VP9_HIGHBITDEPTH
93 int use_highbitdepth,97 int use_highbitdepth,
94#endif98#endif
vp9/encoder/vp9_encoder.c+16−6
@@ -2861,18 +2861,26 @@ void vp9_update_reference_frames(VP9_COMP *cpi) { · 2860 unmodified lines
2861 if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi) &&2861 if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi) &&
2862 cpi->denoiser.denoising_level > kDenLowLow) {2862 cpi->denoiser.denoising_level > kDenLowLow) {
2863 int svc_base_is_key = 0;2863 int svc_base_is_key = 0;
2864 int denoise_svc_second_layer = 0;
2864 if (cpi->use_svc) {2865 if (cpi->use_svc) {
2865 int realloc_fail = 0;2866 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;
2866 int layer = LAYER_IDS_TO_IDX(cpi->svc.spatial_layer_id,2871 int layer = LAYER_IDS_TO_IDX(cpi->svc.spatial_layer_id,
2867 cpi->svc.temporal_layer_id,2872 cpi->svc.temporal_layer_id,
2868 cpi->svc.number_temporal_layers);2873 cpi->svc.number_temporal_layers);
2869 LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer];2874 LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer];
2870 svc_base_is_key = lc->is_key_frame;2875 svc_base_is_key = lc->is_key_frame;
2871 2876 denoise_svc_second_layer =
2872 // Check if we need to allocate extra buffers in the denoiser for2877 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
2873 // refreshed frames.2881 // refreshed frames.
2874 realloc_fail = vp9_denoiser_realloc_svc(2882 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,
2876 cpi->refresh_golden_frame, cpi->refresh_last_frame, cpi->alt_fb_idx,2884 cpi->refresh_golden_frame, cpi->refresh_last_frame, cpi->alt_fb_idx,
2877 cpi->gld_fb_idx, cpi->lst_fb_idx);2885 cpi->gld_fb_idx, cpi->lst_fb_idx);
2878 if (realloc_fail)2886 if (realloc_fail)
@@ -2883,7 +2891,8 @@ void vp9_update_reference_frames(VP9_COMP *cpi) { · 4 unmodified lines
2883 &cpi->denoiser, *cpi->Source, cpi->common.frame_type,2891 &cpi->denoiser, *cpi->Source, cpi->common.frame_type,
2884 cpi->refresh_alt_ref_frame, cpi->refresh_golden_frame,2892 cpi->refresh_alt_ref_frame, cpi->refresh_golden_frame,
2885 cpi->refresh_last_frame, cpi->alt_fb_idx, cpi->gld_fb_idx,2893 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);
2887 }2896 }
2888#endif2897#endif
2889 if (is_one_pass_cbr_svc(cpi)) {2898 if (is_one_pass_cbr_svc(cpi)) {
@@ -3318,8 +3327,9 @@ static void setup_denoiser_buffer(VP9_COMP *cpi) { · 428 unmodified lines
3318 VP9_COMMON *const cm = &cpi->common;3327 VP9_COMMON *const cm = &cpi->common;
3319 if (cpi->oxcf.noise_sensitivity > 0 &&3328 if (cpi->oxcf.noise_sensitivity > 0 &&
3320 !cpi->denoiser.frame_buffer_initialized) {3329 !cpi->denoiser.frame_buffer_initialized) {
3321 if (vp9_denoiser_alloc(cm, cpi->use_svc, &cpi->denoiser, cm->width,3330 if (vp9_denoiser_alloc(cm, &cpi->svc, &cpi->denoiser, cpi->use_svc,
3322 cm->height, cm->subsampling_x, cm->subsampling_y,3331 cpi->oxcf.noise_sensitivity, cm->width, cm->height,
3332 cm->subsampling_x, cm->subsampling_y,
3323#if CONFIG_VP9_HIGHBITDEPTH3333#if CONFIG_VP9_HIGHBITDEPTH
3324 cm->use_highbitdepth,3334 cm->use_highbitdepth,
3325#endif3335#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
870static INLINE int denoise_svc(const struct VP9_COMP *const cpi) {870static INLINE int denoise_svc(const struct VP9_COMP *const cpi) {
871 return (!cpi->use_svc ||871 return (!cpi->use_svc ||
872 (cpi->use_svc &&872 (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));
874}874}
875#endif875#endif
876 876
vp9/encoder/vp9_noise_estimate.c+15−6
@@ -21,6 +21,15 @@ · 20 unmodified lines
21#include "vp9/encoder/vp9_noise_estimate.h"21#include "vp9/encoder/vp9_noise_estimate.h"
22#include "vp9/encoder/vp9_encoder.h"22#include "vp9/encoder/vp9_encoder.h"
23 23
24#if CONFIG_VP9_TEMPORAL_DENOISING
25// For SVC: only do noise estimation on top spatial layer.
26static 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
24void vp9_noise_estimate_init(NOISE_ESTIMATE *const ne, int width, int height) {33void vp9_noise_estimate_init(NOISE_ESTIMATE *const ne, int width, int height) {
25 ne->enabled = 0;34 ne->enabled = 0;
26 ne->level = kLowLow;35 ne->level = kLowLow;
@@ -45,7 +54,7 @@ static int enable_noise_estimation(VP9_COMP *const cpi) { · 18 unmodified lines
45#endif54#endif
46// Enable noise estimation if denoising is on.55// Enable noise estimation if denoising is on.
47#if CONFIG_VP9_TEMPORAL_DENOISING56#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) &&
49 cpi->common.width >= 320 && cpi->common.height >= 180)58 cpi->common.width >= 320 && cpi->common.height >= 180)
50 return 1;59 return 1;
51#endif60#endif
@@ -111,7 +120,7 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) { · 59 unmodified lines
111 // Estimate is between current source and last source.120 // Estimate is between current source and last source.
112 YV12_BUFFER_CONFIG *last_source = cpi->Last_Source;121 YV12_BUFFER_CONFIG *last_source = cpi->Last_Source;
113#if CONFIG_VP9_TEMPORAL_DENOISING122#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)) {
115 last_source = &cpi->denoiser.last_source;124 last_source = &cpi->denoiser.last_source;
116 // Tune these thresholds for different resolutions when denoising is125 // Tune these thresholds for different resolutions when denoising is
117 // enabled.126 // enabled.
@@ -131,7 +140,7 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) { · 13 unmodified lines
131 (cpi->svc.number_spatial_layers == 1 &&140 (cpi->svc.number_spatial_layers == 1 &&
132 (ne->last_w != cm->width || ne->last_h != cm->height))) {141 (ne->last_w != cm->width || ne->last_h != cm->height))) {
133#if CONFIG_VP9_TEMPORAL_DENOISING142#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))
135 copy_frame(&cpi->denoiser.last_source, cpi->Source);144 copy_frame(&cpi->denoiser.last_source, cpi->Source);
136#endif145#endif
137 if (last_source != NULL) {146 if (last_source != NULL) {
@@ -146,7 +155,7 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) { · 8 unmodified lines
146 ne->count = 0;155 ne->count = 0;
147 ne->num_frames_estimate = 10;156 ne->num_frames_estimate = 10;
148#if CONFIG_VP9_TEMPORAL_DENOISING157#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) &&
150 cpi->svc.current_superframe > 1) {159 cpi->svc.current_superframe > 1) {
151 vp9_denoiser_set_noise_level(&cpi->denoiser, ne->level);160 vp9_denoiser_set_noise_level(&cpi->denoiser, ne->level);
152 copy_frame(&cpi->denoiser.last_source, cpi->Source);161 copy_frame(&cpi->denoiser.last_source, cpi->Source);
@@ -257,14 +266,14 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) { · 104 unmodified lines
257 ne->count = 0;266 ne->count = 0;
258 ne->level = vp9_noise_estimate_extract_level(ne);267 ne->level = vp9_noise_estimate_extract_level(ne);
259#if CONFIG_VP9_TEMPORAL_DENOISING268#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))
261 vp9_denoiser_set_noise_level(&cpi->denoiser, ne->level);270 vp9_denoiser_set_noise_level(&cpi->denoiser, ne->level);
262#endif271#endif
263 }272 }
264 }273 }
265 }274 }
266#if CONFIG_VP9_TEMPORAL_DENOISING275#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))
268 copy_frame(&cpi->denoiser.last_source, cpi->Source);277 copy_frame(&cpi->denoiser.last_source, cpi->Source);
269#endif278#endif
270}279}
vp9/encoder/vp9_svc_layercontext.c+4−3
@@ -37,6 +37,7 @@ void vp9_init_layer_context(VP9_COMP *const cpi) { · 36 unmodified lines
37 svc->scaled_one_half = 0;37 svc->scaled_one_half = 0;
38 svc->current_superframe = 0;38 svc->current_superframe = 0;
39 svc->non_reference_frame = 0;39 svc->non_reference_frame = 0;
40
40 for (i = 0; i < REF_FRAMES; ++i) svc->ref_frame_index[i] = -1;41 for (i = 0; i < REF_FRAMES; ++i) svc->ref_frame_index[i] = -1;
41 for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {42 for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
42 svc->ext_frame_flags[sl] = 0;43 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
389 .is_key_frame;390 .is_key_frame;
390}391}
391 392
392static void get_layer_resolution(const int width_org, const int height_org,393void get_layer_resolution(const int width_org, const int height_org,
393 const int num, const int den, int *width_out,394 const int num, const int den, int *width_out,
394 int *height_out) {395 int *height_out) {
395 int w, h;396 int w, h;
396 397
397 if (width_out == NULL || height_out == NULL || den == 0) return;398 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
49 uint8_t speed;49 uint8_t speed;
50} LAYER_CONTEXT;50} LAYER_CONTEXT;
51 51
52typedef struct {52typedef struct SVC {
53 int spatial_layer_id;53 int spatial_layer_id;
54 int temporal_layer_id;54 int temporal_layer_id;
55 int number_spatial_layers;55 int number_spatial_layers;
@@ -99,6 +99,8 @@ typedef struct { · 43 unmodified lines
99 99
100 BLOCK_SIZE *prev_partition_svc;100 BLOCK_SIZE *prev_partition_svc;
101 int mi_stride[VPX_MAX_LAYERS];101 int mi_stride[VPX_MAX_LAYERS];
102
103 int first_layer_denoise;
102} SVC;104} SVC;
103 105
104struct VP9_COMP;106struct VP9_COMP;
@@ -128,6 +130,10 @@ void vp9_save_layer_context(struct VP9_COMP *const cpi); · 23 unmodified lines
128// Initialize second pass rc for spatial svc.130// Initialize second pass rc for spatial svc.
129void vp9_init_second_pass_spatial_svc(struct VP9_COMP *cpi);131void vp9_init_second_pass_spatial_svc(struct VP9_COMP *cpi);
130 132
133void 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
131// Increment number of video frames in layer137// Increment number of video frames in layer
132void vp9_inc_frame_in_layer(struct VP9_COMP *const cpi);138void vp9_inc_frame_in_layer(struct VP9_COMP *const cpi);
133 139
vpx/vp8cx.h+1−1
@@ -408,7 +408,7 @@ enum vp8e_enc_control_id { · 407 unmodified lines
408 408
409 /*!\brief Codec control function to set noise sensitivity.409 /*!\brief Codec control function to set noise sensitivity.
410 *410 *
411 * 0: off, 1: On(YOnly)411 * 0: off, 1: On(YOnly), 2: For SVC only, on top two spatial layers(YOnly)
412 *412 *
413 * Supported in codecs: VP9413 * Supported in codecs: VP9
414 */414 */

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