From fe5dc9f7fc2f98709184dace2308d51265f2800d Mon Sep 17 00:00:00 2001 From: Jerome Jiang Date: Fri, 10 Nov 2023 20:38:31 -0500 Subject: [PATCH] vp9 rc: support screen content Bug: b/281463780 Change-Id: I23668550257b28031bdca0537459f93ec63f1e2e --- test/vp9_ratectrl_rtc_test.cc | 21 ++++++++++++++++++++- vp9/encoder/vp9_encoder.c | 1 + vp9/encoder/vp9_encoder.h | 3 +++ vp9/encoder/vp9_ratectrl.c | 3 ++- vp9/ratectrl_rtc.cc | 1 + vp9/vp9_cx_iface.c | 1 + vpx/internal/vpx_ratectrl_rtc.h | 2 ++ 7 files changed, 30 insertions(+), 2 deletions(-) diff --git a/test/vp9_ratectrl_rtc_test.cc b/test/vp9_ratectrl_rtc_test.cc index ff718bb..f7be475 100644 --- a/test/vp9_ratectrl_rtc_test.cc +++ b/test/vp9_ratectrl_rtc_test.cc @@ -54,7 +54,11 @@ class RcInterfaceTest if (video->frame() == 0) { encoder->Control(VP8E_SET_CPUUSED, 7); encoder->Control(VP9E_SET_AQ_MODE, aq_mode_); - encoder->Control(VP9E_SET_TUNE_CONTENT, 0); + if (rc_cfg_.is_screen) { + encoder->Control(VP9E_SET_TUNE_CONTENT, VP9E_CONTENT_SCREEN); + } else { + encoder->Control(VP9E_SET_TUNE_CONTENT, VP9E_CONTENT_DEFAULT); + } encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 1000); encoder->Control(VP9E_SET_RTC_EXTERNAL_RATECTRL, 1); } @@ -101,6 +105,19 @@ class RcInterfaceTest ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); } + void RunOneLayerScreen() { + SetConfig(GET_PARAM(2)); + rc_cfg_.is_screen = true; + rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); + frame_params_.spatial_layer_id = 0; + frame_params_.temporal_layer_id = 0; + + ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", + 1280, 720, 30, 1, 0, kNumFrames); + + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + } + void RunOneLayerDropFramesCBR() { if (GET_PARAM(2) != VPX_CBR) { GTEST_SKIP() << "Frame dropping is only for CBR mode."; @@ -632,6 +649,8 @@ TEST_P(RcInterfaceTest, OneLayer) { RunOneLayer(); } TEST_P(RcInterfaceTest, OneLayerDropFramesCBR) { RunOneLayerDropFramesCBR(); } +TEST_P(RcInterfaceTest, OneLayerScreen) { RunOneLayerScreen(); } + TEST_P(RcInterfaceTest, OneLayerVBRPeriodicKey) { RunOneLayerVBRPeriodicKey(); } TEST_P(RcInterfaceSvcTest, Svc) { RunSvc(); } diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index e27a77e..be55150 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -4065,6 +4065,7 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size, cpi->rc.hybrid_intra_scene_change = 0; cpi->rc.re_encode_maxq_scene_change = 0; if (cm->show_frame && cpi->oxcf.mode == REALTIME && + !cpi->disable_scene_detection_rtc_ratectrl && (cpi->oxcf.rc_mode == VPX_VBR || cpi->oxcf.content == VP9E_CONTENT_SCREEN || (cpi->oxcf.speed >= 5 && cpi->oxcf.speed < 8))) diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 1714893..160de00 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -1041,6 +1041,9 @@ typedef struct VP9_COMP { // (good/best/realtime). MODE deadline_mode_previous_frame; + // Flag to disable scene detection when rtc rate control library is used. + int disable_scene_detection_rtc_ratectrl; + #if CONFIG_COLLECT_COMPONENT_TIMING /*! * component_time[] are initialized to zero while encoder starts. diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index aa77b7c..6452e34 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -680,7 +680,8 @@ static int adjust_q_cbr(const VP9_COMP *cpi, int q) { else q = qclamp; } - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) + if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && + cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) vp9_cyclic_refresh_limit_q(cpi, &q); return VPXMAX(VPXMIN(q, cpi->rc.worst_quality), cpi->rc.best_quality); } diff --git a/vp9/ratectrl_rtc.cc b/vp9/ratectrl_rtc.cc index d823971..fd81bce 100644 --- a/vp9/ratectrl_rtc.cc +++ b/vp9/ratectrl_rtc.cc @@ -131,6 +131,7 @@ bool VP9RateControlRTC::UpdateRateControl( oxcf->under_shoot_pct = rc_cfg.undershoot_pct; oxcf->over_shoot_pct = rc_cfg.overshoot_pct; oxcf->drop_frames_water_mark = rc_cfg.frame_drop_thresh; + oxcf->content = rc_cfg.is_screen ? VP9E_CONTENT_SCREEN : VP9E_CONTENT_DEFAULT; oxcf->ss_number_layers = rc_cfg.ss_number_layers; oxcf->ts_number_layers = rc_cfg.ts_number_layers; oxcf->temporal_layering_mode = (VP9E_TEMPORAL_LAYERING_MODE)( diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index b1dfe99..b75fc18 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -1077,6 +1077,7 @@ static vpx_codec_err_t ctrl_set_rtc_external_ratectrl(vpx_codec_alg_priv_t *ctx, cpi->compute_frame_low_motion_onepass = 0; cpi->rc.constrain_gf_key_freq_onepass_vbr = 0; cpi->cyclic_refresh->content_mode = 0; + cpi->disable_scene_detection_rtc_ratectrl = 1; } return VPX_CODEC_OK; } diff --git a/vpx/internal/vpx_ratectrl_rtc.h b/vpx/internal/vpx_ratectrl_rtc.h index 6ffd798..01d64b1 100644 --- a/vpx/internal/vpx_ratectrl_rtc.h +++ b/vpx/internal/vpx_ratectrl_rtc.h @@ -43,6 +43,7 @@ struct VpxRateControlRtcConfig { layer_target_bitrate[0] = static_cast(target_bandwidth); ts_rate_decimator[0] = 1; frame_drop_thresh = 0; + is_screen = false; } int width; @@ -67,6 +68,7 @@ struct VpxRateControlRtcConfig { enum vpx_rc_mode rc_mode; int aq_mode; int frame_drop_thresh; + bool is_screen; }; } // namespace libvpx #endif // VPX_VPX_INTERNAL_VPX_RATECTRL_RTC_H_ -- 2.7.4