diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index fc05811a3..59788eb82 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -183,6 +183,33 @@ int vp9_set_active_map(VP9_COMP* cpi, } } +int vp9_get_active_map(VP9_COMP* cpi, + unsigned char* new_map_16x16, + int rows, + int cols) { + if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols && + new_map_16x16) { + unsigned char* const seg_map_8x8 = cpi->segmentation_map; + const int mi_rows = cpi->common.mi_rows; + const int mi_cols = cpi->common.mi_cols; + vpx_memset(new_map_16x16, !cpi->active_map.enabled, rows * cols); + if (cpi->active_map.enabled) { + int r, c; + for (r = 0; r < mi_rows; ++r) { + for (c = 0; c < mi_cols; ++c) { + // Cyclic refresh segments are considered active despite not having + // AM_SEGMENT_ID_ACTIVE + new_map_16x16[(r >> 1) * cols + (c >> 1)] |= + seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE; + } + } + } + return 0; + } else { + return -1; + } +} + void vp9_set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) { MACROBLOCK *const mb = &cpi->td.mb; cpi->common.allow_high_precision_mv = allow_high_precision_mv; diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 914080c6f..3c57c8613 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -508,6 +508,8 @@ int vp9_update_entropy(VP9_COMP *cpi, int update); int vp9_set_active_map(VP9_COMP *cpi, unsigned char *map, int rows, int cols); +int vp9_get_active_map(VP9_COMP *cpi, unsigned char *map, int rows, int cols); + int vp9_set_internal_size(VP9_COMP *cpi, VPX_SCALING horiz_mode, VPX_SCALING vert_mode); diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index 0ce37aae7..cba15e693 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -1260,6 +1260,21 @@ static vpx_codec_err_t ctrl_set_active_map(vpx_codec_alg_priv_t *ctx, } } +static vpx_codec_err_t ctrl_get_active_map(vpx_codec_alg_priv_t *ctx, + va_list args) { + vpx_active_map_t *const map = va_arg(args, vpx_active_map_t *); + + if (map) { + if (!vp9_get_active_map(ctx->cpi, map->active_map, + (int)map->rows, (int)map->cols)) + return VPX_CODEC_OK; + else + return VPX_CODEC_INVALID_PARAM; + } else { + return VPX_CODEC_INVALID_PARAM; + } +} + static vpx_codec_err_t ctrl_set_scale_mode(vpx_codec_alg_priv_t *ctx, va_list args) { vpx_scaling_mode_t *const mode = va_arg(args, vpx_scaling_mode_t *); @@ -1417,6 +1432,7 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { #if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION) {VP9E_GET_SVC_LAYER_ID, ctrl_get_svc_layer_id}, #endif + {VP9E_GET_ACTIVEMAP, ctrl_get_active_map}, { -1, NULL}, }; diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h index 60b588f0e..0e8adc134 100644 --- a/vpx/vp8cx.h +++ b/vpx/vp8cx.h @@ -508,6 +508,12 @@ enum vp8e_enc_control_id { * Supported in codecs: VP9 */ VP9E_SET_COLOR_SPACE, + + /*!\brief Codec control function to get an Active map back from the encoder. + * + * Supported in codecs: VP9 + */ + VP9E_GET_ACTIVEMAP, }; /*!\brief vpx 1-D scaling mode @@ -691,6 +697,8 @@ VPX_CTRL_USE_TYPE(VP9E_SET_NOISE_SENSITIVITY, unsigned int) VPX_CTRL_USE_TYPE(VP9E_SET_TUNE_CONTENT, int) /* vp9e_tune_content */ VPX_CTRL_USE_TYPE(VP9E_SET_COLOR_SPACE, int) + +VPX_CTRL_USE_TYPE(VP9E_GET_ACTIVEMAP, vpx_active_map_t *) /*! @} - end defgroup vp8_encoder */ #ifdef __cplusplus } // extern "C"