diff options
author | Jerome Jiang <jianj@google.com> | 2017-10-18 18:16:44 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2017-10-18 18:16:44 +0000 |
commit | ec2fced451c634b73055631617e0dd5b8e26b9ed (patch) | |
tree | 5ba16615c1aad07735346cfa591818868f21116f | |
parent | b3a36f7946f930caa0e96448648db60d7330c98d (diff) | |
parent | dbb8926b86610684c4a2e3aba503aa0222cd951d (diff) | |
download | libvpx-ec2fced451c634b73055631617e0dd5b8e26b9ed.tar libvpx-ec2fced451c634b73055631617e0dd5b8e26b9ed.tar.gz libvpx-ec2fced451c634b73055631617e0dd5b8e26b9ed.tar.bz2 libvpx-ec2fced451c634b73055631617e0dd5b8e26b9ed.zip |
Merge "vp8: Enable use of ROI map."
-rw-r--r-- | examples/vpx_temporal_svc_encoder.c | 58 | ||||
-rw-r--r-- | test/set_roi.cc | 8 | ||||
-rw-r--r-- | vp8/encoder/onyx_if.c | 19 | ||||
-rw-r--r-- | vp8/encoder/onyx_int.h | 3 |
4 files changed, 74 insertions, 14 deletions
diff --git a/examples/vpx_temporal_svc_encoder.c b/examples/vpx_temporal_svc_encoder.c index 72ea396d1..bff6e1722 100644 --- a/examples/vpx_temporal_svc_encoder.c +++ b/examples/vpx_temporal_svc_encoder.c @@ -26,6 +26,8 @@ #include "../tools_common.h" #include "../video_writer.h" +#define VP8_ROI_MAP 0 + static const char *exec_name; void usage_exit(void) { exit(EXIT_FAILURE); } @@ -154,6 +156,53 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc, die("Error: Number of input frames not equal to output! \n"); } +#if VP8_ROI_MAP +static void vp8_set_roi_map(vpx_codec_enc_cfg_t *cfg, vpx_roi_map_t *roi) { + unsigned int i, j; + memset(roi, 0, sizeof(*roi)); + + // ROI is based on the segments (4 for vp8, 8 for vp9), smallest unit for + // segment is 16x16 for vp8, 8x8 for vp9. + roi->rows = (cfg->g_h + 15) / 16; + roi->cols = (cfg->g_w + 15) / 16; + + // Applies delta QP on the segment blocks, varies from -63 to 63. + // Setting to negative means lower QP (better quality). + // Below we set delta_q to the extreme (-63) to show strong effect. + roi->delta_q[0] = 0; + roi->delta_q[1] = -63; + roi->delta_q[2] = 0; + roi->delta_q[3] = 0; + + // Applies delta loopfilter strength on the segment blocks, varies from -63 to + // 63. Setting to positive means stronger loopfilter. + roi->delta_lf[0] = 0; + roi->delta_lf[1] = 0; + roi->delta_lf[2] = 0; + roi->delta_lf[3] = 0; + + // Applies skip encoding threshold on the segment blocks, varies from 0 to + // UINT_MAX. Larger value means more skipping of encoding is possible. + // This skip threshold only applies on delta frames. + roi->static_threshold[0] = 0; + roi->static_threshold[1] = 0; + roi->static_threshold[2] = 0; + roi->static_threshold[3] = 0; + + // Use 2 states: 1 is center square, 0 is the rest. + roi->roi_map = + (uint8_t *)calloc(roi->rows * roi->cols, sizeof(*roi->roi_map)); + for (i = 0; i < roi->rows; ++i) { + for (j = 0; j < roi->cols; ++j) { + if (i > (roi->rows >> 2) && i < ((roi->rows * 3) >> 2) && + j > (roi->cols >> 2) && j < ((roi->cols * 3) >> 2)) { + roi->roi_map[i * roi->cols + j] = 1; + } + } + } +} +#endif + // Temporal scaling parameters: // NOTE: The 3 prediction frames cannot be used interchangeably due to // differences in the way they are handled throughout the code. The @@ -506,6 +555,9 @@ int main(int argc, char **argv) { int layering_mode = 0; int layer_flags[VPX_TS_MAX_PERIODICITY] = { 0 }; int flag_periodicity = 1; +#if VP8_ROI_MAP + vpx_roi_map_t roi; +#endif #if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION) vpx_svc_layer_id_t layer_id = { 0, 0 }; #else @@ -710,6 +762,12 @@ int main(int argc, char **argv) { vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff); vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1); vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0); +#if VP8_ROI_MAP + vp8_set_roi_map(&cfg, &roi); + if (vpx_codec_control(&codec, VP8E_SET_ROI_MAP, &roi)) + die_codec(&codec, "Failed to set ROI map"); +#endif + } else if (strncmp(encoder->name, "vp9", 3) == 0) { vpx_svc_extra_cfg_t svc_params; memset(&svc_params, 0, sizeof(svc_params)); diff --git a/test/set_roi.cc b/test/set_roi.cc index 38711a806..f63954752 100644 --- a/test/set_roi.cc +++ b/test/set_roi.cc @@ -146,14 +146,6 @@ TEST(VP8RoiMapTest, ParameterCheck) { if (deltas_valid != roi_retval) break; } - // Test that we report and error if cyclic refresh is enabled. - cpi.cyclic_refresh_mode_enabled = 1; - roi_retval = - vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols, - delta_q, delta_lf, threshold); - EXPECT_EQ(-1, roi_retval) << "cyclic refresh check error"; - cpi.cyclic_refresh_mode_enabled = 0; - // Test invalid number of rows or colums. roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1, diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 2c2a783a9..5d714e122 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -1553,9 +1553,8 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) { setup_features(cpi); - { + if (!cpi->use_roi_static_threshold) { int i; - for (i = 0; i < MAX_MB_SEGMENTS; ++i) { cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout; } @@ -1815,6 +1814,8 @@ struct VP8_COMP *vp8_create_compressor(VP8_CONFIG *oxcf) { cpi->active_map_enabled = 0; + cpi->use_roi_static_threshold = 0; + #if 0 /* Experimental code for lagged and one pass */ /* Initialise one_pass GF frames stats */ @@ -5354,9 +5355,6 @@ int vp8_set_roimap(VP8_COMP *cpi, unsigned char *map, unsigned int rows, const int range = 63; int i; - // This method is currently incompatible with the cyclic refresh method - if (cpi->cyclic_refresh_mode_enabled) return -1; - // Check number of rows and columns match if (cpi->common.mb_rows != (int)rows || cpi->common.mb_cols != (int)cols) { return -1; @@ -5375,7 +5373,11 @@ int vp8_set_roimap(VP8_COMP *cpi, unsigned char *map, unsigned int rows, return -1; } - if (!map) { + // Also disable segmentation if no deltas are specified. + if (!map || (delta_q[0] == 0 && delta_q[1] == 0 && delta_q[2] == 0 && + delta_q[3] == 0 && delta_lf[0] == 0 && delta_lf[1] == 0 && + delta_lf[2] == 0 && delta_lf[3] == 0 && threshold[0] == 0 && + threshold[1] == 0 && threshold[2] == 0 && threshold[3] == 0)) { disable_segmentation(cpi); return 0; } @@ -5412,6 +5414,11 @@ int vp8_set_roimap(VP8_COMP *cpi, unsigned char *map, unsigned int rows, /* Initialise the feature data structure */ set_segment_data(cpi, &feature_data[0][0], SEGMENT_DELTADATA); + if (threshold[0] != 0 || threshold[1] != 0 || threshold[2] != 0 || + threshold[3] != 0) + cpi->use_roi_static_threshold = 1; + cpi->cyclic_refresh_mode_enabled = 0; + return 0; } diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 0ee2d3553..c489b46c2 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -692,6 +692,9 @@ typedef struct VP8_COMP { int token_costs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; } rd_costs; + + // Use the static threshold from ROI settings. + int use_roi_static_threshold; } VP8_COMP; void vp8_initialize_enc(void); |