summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Jiang <jianj@google.com>2020-01-16 23:17:26 -0800
committerJerome Jiang <jianj@google.com>2020-01-17 09:19:23 -0800
commit49aa77c61fc1d2dc369594fb19c3165f9c56bd18 (patch)
tree6f1902f24ab54a0bb4b7f3bec02078db778ce0f9
parent18e93be9f2e9c863be573e910ff6940547fa0cad (diff)
downloadlibvpx-49aa77c61fc1d2dc369594fb19c3165f9c56bd18.tar
libvpx-49aa77c61fc1d2dc369594fb19c3165f9c56bd18.tar.gz
libvpx-49aa77c61fc1d2dc369594fb19c3165f9c56bd18.tar.bz2
libvpx-49aa77c61fc1d2dc369594fb19c3165f9c56bd18.zip
vp9: add delta q for uv channel. add tests.
Add control for delta q for uv. 0 by default. Change-Id: Ib8ed160b1a5c9a61ba15985076f6c6f121477103
-rw-r--r--test/vp9_datarate_test.cc56
-rw-r--r--vp9/encoder/vp9_encoder.c8
-rw-r--r--vp9/encoder/vp9_encoder.h1
-rw-r--r--vp9/encoder/vp9_firstpass.c2
-rw-r--r--vp9/encoder/vp9_quantize.c7
-rw-r--r--vp9/encoder/vp9_quantize.h2
-rw-r--r--vp9/vp9_cx_iface.c12
-rw-r--r--vpx/vp8cx.h11
8 files changed, 92 insertions, 7 deletions
diff --git a/test/vp9_datarate_test.cc b/test/vp9_datarate_test.cc
index b8be275ea..f9f2aaaff 100644
--- a/test/vp9_datarate_test.cc
+++ b/test/vp9_datarate_test.cc
@@ -46,6 +46,7 @@ class DatarateTestVP9 : public ::libvpx_test::EncoderTest {
denoiser_offon_test_ = 0;
denoiser_offon_period_ = -1;
frame_parallel_decoding_mode_ = 1;
+ delta_q_uv_ = 0;
use_roi_ = false;
}
@@ -138,6 +139,10 @@ class DatarateTestVP9 : public ::libvpx_test::EncoderTest {
encoder->Control(VP9E_SET_AQ_MODE, 0);
}
+ if (delta_q_uv_ != 0) {
+ encoder->Control(VP9E_SET_DELTA_Q_UV, delta_q_uv_);
+ }
+
if (cfg_.ts_number_layers > 1) {
if (video->frame() == 0) {
encoder->Control(VP9E_SET_SVC, 1);
@@ -222,6 +227,7 @@ class DatarateTestVP9 : public ::libvpx_test::EncoderTest {
int denoiser_offon_test_;
int denoiser_offon_period_;
int frame_parallel_decoding_mode_;
+ int delta_q_uv_;
bool use_roi_;
vpx_roi_map_t roi_;
};
@@ -716,6 +722,52 @@ TEST_P(DatarateTestVP9RealTime, RegionOfInterest) {
free(roi_.roi_map);
}
+// Params: speed setting, delta q UV.
+class DatarateTestVP9RealTimeDeltaQUV
+ : public DatarateTestVP9,
+ public ::libvpx_test::CodecTestWith2Params<int, int> {
+ public:
+ DatarateTestVP9RealTimeDeltaQUV() : DatarateTestVP9(GET_PARAM(0)) {}
+ virtual ~DatarateTestVP9RealTimeDeltaQUV() {}
+
+ protected:
+ virtual void SetUp() {
+ InitializeConfig();
+ SetMode(::libvpx_test::kRealTime);
+ set_cpu_used_ = GET_PARAM(1);
+ ResetModel();
+ }
+};
+
+TEST_P(DatarateTestVP9RealTimeDeltaQUV, DeltaQUV) {
+ cfg_.rc_buf_initial_sz = 500;
+ cfg_.rc_buf_optimal_sz = 500;
+ cfg_.rc_buf_sz = 1000;
+ cfg_.rc_dropframe_thresh = 0;
+ cfg_.rc_min_quantizer = 0;
+ cfg_.rc_max_quantizer = 63;
+ cfg_.rc_end_usage = VPX_CBR;
+ cfg_.g_lag_in_frames = 0;
+
+ ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
+ 0, 400);
+
+ cfg_.rc_target_bitrate = 450;
+ cfg_.g_w = 640;
+ cfg_.g_h = 480;
+
+ ResetModel();
+
+ delta_q_uv_ = GET_PARAM(2);
+
+ ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+ ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_[0] * 0.90)
+ << " The datarate for the file exceeds the target!";
+
+ ASSERT_LE(cfg_.rc_target_bitrate, effective_datarate_[0] * 1.4)
+ << " The datarate for the file missed the target!";
+}
+
// Params: test mode, speed setting and index for bitrate array.
class DatarateTestVP9PostEncodeDrop
: public DatarateTestVP9,
@@ -891,6 +943,10 @@ VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9LargeVBR, ::testing::Range(5, 9),
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9RealTime, ::testing::Range(5, 10));
+VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9RealTimeDeltaQUV,
+ ::testing::Range(5, 10),
+ ::testing::Values(-5, -10, -15));
+
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9PostEncodeDrop,
::testing::Range(5, 6));
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 9b03b2099..182064c48 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -4065,7 +4065,7 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
cpi->oxcf.rc_mode == VPX_CBR &&
cm->frame_type != KEY_FRAME;
- vp9_set_quantizer(cm, q);
+ vp9_set_quantizer(cpi, q);
vp9_set_variance_partition_thresholds(cpi, q, 0);
setup_frame(cpi);
@@ -4094,7 +4094,7 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
(cpi->rc.high_source_sad ||
(cpi->use_svc && svc->high_source_sad_superframe))) {
if (vp9_encodedframe_overshoot(cpi, -1, &q)) {
- vp9_set_quantizer(cm, q);
+ vp9_set_quantizer(cpi, q);
vp9_set_variance_partition_thresholds(cpi, q, 0);
}
}
@@ -4144,7 +4144,7 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
// adjust some rate control parameters, and return to re-encode the frame.
if (vp9_encodedframe_overshoot(cpi, frame_size, &q)) {
vpx_clear_system_state();
- vp9_set_quantizer(cm, q);
+ vp9_set_quantizer(cpi, q);
vp9_set_variance_partition_thresholds(cpi, q, 0);
suppress_active_map(cpi);
// Turn-off cyclic refresh for re-encoded frame.
@@ -4294,7 +4294,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
}
#endif
- vp9_set_quantizer(cm, q);
+ vp9_set_quantizer(cpi, q);
if (loop_count == 0) setup_frame(cpi);
diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h
index c2bdebb4d..388653ddc 100644
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -282,6 +282,7 @@ typedef struct VP9EncoderConfig {
int row_mt;
unsigned int motion_vector_unit_test;
+ int delta_q_uv;
} VP9EncoderConfig;
static INLINE int is_lossless_requested(const VP9EncoderConfig *cfg) {
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index cfaa68cfa..ba35e6b9c 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -1366,7 +1366,7 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
#endif
set_first_pass_params(cpi);
- vp9_set_quantizer(cm, find_fp_qindex(cm->bit_depth));
+ vp9_set_quantizer(cpi, find_fp_qindex(cm->bit_depth));
vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
diff --git a/vp9/encoder/vp9_quantize.c b/vp9/encoder/vp9_quantize.c
index 26d1434c3..c996b7516 100644
--- a/vp9/encoder/vp9_quantize.c
+++ b/vp9/encoder/vp9_quantize.c
@@ -323,13 +323,18 @@ void vp9_frame_init_quantizer(VP9_COMP *cpi) {
vp9_init_plane_quantizers(cpi, &cpi->td.mb);
}
-void vp9_set_quantizer(VP9_COMMON *cm, int q) {
+void vp9_set_quantizer(VP9_COMP *cpi, int q) {
+ VP9_COMMON *cm = &cpi->common;
// quantizer has to be reinitialized with vp9_init_quantizer() if any
// delta_q changes.
cm->base_qindex = q;
cm->y_dc_delta_q = 0;
cm->uv_dc_delta_q = 0;
cm->uv_ac_delta_q = 0;
+ if (cpi->oxcf.delta_q_uv != 0) {
+ cm->uv_dc_delta_q = cm->uv_ac_delta_q = cpi->oxcf.delta_q_uv;
+ vp9_init_quantizer(cpi);
+ }
}
// Table that converts 0-63 Q-range values passed in outside to the Qindex
diff --git a/vp9/encoder/vp9_quantize.h b/vp9/encoder/vp9_quantize.h
index ed9b84958..2e6d7da2b 100644
--- a/vp9/encoder/vp9_quantize.h
+++ b/vp9/encoder/vp9_quantize.h
@@ -49,7 +49,7 @@ void vp9_init_plane_quantizers(struct VP9_COMP *cpi, MACROBLOCK *x);
void vp9_init_quantizer(struct VP9_COMP *cpi);
-void vp9_set_quantizer(struct VP9Common *cm, int q);
+void vp9_set_quantizer(struct VP9_COMP *cm, int q);
int vp9_quantizer_to_qindex(int quantizer);
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index f415e50f7..baea0ece1 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -581,6 +581,8 @@ static vpx_codec_err_t set_encoder_config(
oxcf->min_gf_interval = extra_cfg->min_gf_interval;
oxcf->max_gf_interval = extra_cfg->max_gf_interval;
+ oxcf->delta_q_uv = 0;
+
oxcf->tuning = extra_cfg->tuning;
oxcf->content = extra_cfg->content;
@@ -1655,6 +1657,15 @@ static vpx_codec_err_t ctrl_set_svc_spatial_layer_sync(
return VPX_CODEC_OK;
}
+static vpx_codec_err_t ctrl_set_delta_q_uv(vpx_codec_alg_priv_t *ctx,
+ va_list args) {
+ int data = va_arg(args, int);
+ VP9_COMP *const cpi = ctx->cpi;
+ data = VPXMIN(VPXMAX(data, -20), 20);
+ cpi->oxcf.delta_q_uv = data;
+ return VPX_CODEC_OK;
+}
+
static vpx_codec_err_t ctrl_register_cx_callback(vpx_codec_alg_priv_t *ctx,
va_list args) {
vpx_codec_priv_output_cx_pkt_cb_pair_t *cbp =
@@ -1752,6 +1763,7 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ VP9E_SET_SVC_FRAME_DROP_LAYER, ctrl_set_svc_frame_drop_layer },
{ VP9E_SET_SVC_GF_TEMPORAL_REF, ctrl_set_svc_gf_temporal_ref },
{ VP9E_SET_SVC_SPATIAL_LAYER_SYNC, ctrl_set_svc_spatial_layer_sync },
+ { VP9E_SET_DELTA_Q_UV, ctrl_set_delta_q_uv },
// Getters
{ VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer },
diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h
index 95e2493b1..d8b769b87 100644
--- a/vpx/vp8cx.h
+++ b/vpx/vp8cx.h
@@ -676,6 +676,14 @@ enum vp8e_enc_control_id {
* Supported in codecs: VP9
*/
VP9E_SET_POSTENCODE_DROP,
+
+ /*!\brief Codec control function to set delta q for uv.
+ *
+ * Cap it at +/-20 for now.
+ *
+ * Supported in codecs: VP9
+ */
+ VP9E_SET_DELTA_Q_UV,
};
/*!\brief vpx 1-D scaling mode
@@ -1023,6 +1031,9 @@ VPX_CTRL_USE_TYPE(VP9E_SET_SVC_SPATIAL_LAYER_SYNC,
VPX_CTRL_USE_TYPE(VP9E_SET_POSTENCODE_DROP, unsigned int)
#define VPX_CTRL_VP9E_SET_POSTENCODE_DROP
+VPX_CTRL_USE_TYPE(VP9E_SET_DELTA_Q_UV, int)
+#define VPX_CTRL_VP9E_SET_DELTA_Q_UV
+
/*!\endcond */
/*! @} - end defgroup vp8_encoder */
#ifdef __cplusplus