vp8: Enable use of ROI map.
Disable cyclic refresh if ROI is used and add flag to properly handle the static_thresh deltas. Remove the ROI test for cyclic refresh (it's allowed but disabled if ROI is used). Add an example in vpx_temporal_svc_encoder.c. Turned off by default. BUG=webm:1470 Change-Id: Ief9ba1d7f967bc00511b412b491c3f70943bfbda
This commit is contained in:
parent
a9248457b1
commit
dbb8926b86
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user