Commit 65dd157c authored by Yunqing Wang's avatar Yunqing Wang

multi-res: force Key frame sychronization

In multi-resolution encoding, frame_type decision for each frame
is made by the lowest-resolution encoder. For all other higher-
resolution encoders, kf_mode is always set to VPX_KF_DISABLED,
and they are forced to use the same frame_type picked by the
lowest-resolution encoder.

Change-Id: Ic4d52ec65bbc012ca9c2d236210e28a295591eaf
parent c7ca3808
...@@ -168,7 +168,7 @@ typedef struct ...@@ -168,7 +168,7 @@ typedef struct
} MODE_INFO; } MODE_INFO;
#if CONFIG_MULTI_RES_ENCODING #if CONFIG_MULTI_RES_ENCODING
/* The information needed to be stored for higher-resolution encoder */ /* The mb-level information needed to be stored for higher-resolution encoder */
typedef struct typedef struct
{ {
MB_PREDICTION_MODE mode; MB_PREDICTION_MODE mode;
...@@ -176,7 +176,15 @@ typedef struct ...@@ -176,7 +176,15 @@ typedef struct
int_mv mv; int_mv mv;
//union b_mode_info bmi[16]; //union b_mode_info bmi[16];
int dissim; // dissimilarity level of the macroblock int dissim; // dissimilarity level of the macroblock
} LOWER_RES_INFO; } LOWER_RES_MB_INFO;
/* The frame-level information needed to be stored for higher-resolution
* encoder */
typedef struct
{
FRAME_TYPE frame_type;
LOWER_RES_MB_INFO *mb_info;
} LOWER_RES_FRAME_INFO;
#endif #endif
typedef struct blockd typedef struct blockd
......
...@@ -65,14 +65,18 @@ void vp8_cal_dissimilarity(VP8_COMP *cpi) ...@@ -65,14 +65,18 @@ void vp8_cal_dissimilarity(VP8_COMP *cpi)
/* Store info for show/no-show frames for supporting alt_ref. /* Store info for show/no-show frames for supporting alt_ref.
* If parent frame is alt_ref, child has one too. * If parent frame is alt_ref, child has one too.
*/ */
LOWER_RES_FRAME_INFO* store_info
= (LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info;
store_info->frame_type = cm->frame_type;
if(cm->frame_type != KEY_FRAME) if(cm->frame_type != KEY_FRAME)
{ {
int mb_row; int mb_row;
int mb_col; int mb_col;
/* Point to beginning of allocated MODE_INFO arrays. */ /* Point to beginning of allocated MODE_INFO arrays. */
MODE_INFO *tmp = cm->mip + cm->mode_info_stride; MODE_INFO *tmp = cm->mip + cm->mode_info_stride;
LOWER_RES_INFO* store_mode_info LOWER_RES_MB_INFO* store_mode_info = store_info->mb_info;
= (LOWER_RES_INFO*)cpi->oxcf.mr_low_res_mode_info;
for (mb_row = 0; mb_row < cm->mb_rows; mb_row ++) for (mb_row = 0; mb_row < cm->mb_rows; mb_row ++)
{ {
......
...@@ -3241,6 +3241,17 @@ static void encode_frame_to_data_rate ...@@ -3241,6 +3241,17 @@ static void encode_frame_to_data_rate
cm->frame_type = KEY_FRAME; cm->frame_type = KEY_FRAME;
} }
#if CONFIG_MULTI_RES_ENCODING
/* In multi-resolution encoding, frame_type is decided by lowest-resolution
* encoder. Same frame_type is adopted while encoding at other resolution.
*/
if (cpi->oxcf.mr_encoder_id)
{
cm->frame_type =
((LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info)->frame_type;
}
#endif
// Set default state for segment and mode based loop filter update flags // Set default state for segment and mode based loop filter update flags
cpi->mb.e_mbd.update_mb_segmentation_map = 0; cpi->mb.e_mbd.update_mb_segmentation_map = 0;
cpi->mb.e_mbd.update_mb_segmentation_data = 0; cpi->mb.e_mbd.update_mb_segmentation_data = 0;
......
...@@ -405,8 +405,8 @@ void get_lower_res_motion_info(VP8_COMP *cpi, MACROBLOCKD *xd, int *dissim, ...@@ -405,8 +405,8 @@ void get_lower_res_motion_info(VP8_COMP *cpi, MACROBLOCKD *xd, int *dissim,
MB_PREDICTION_MODE *parent_mode, MB_PREDICTION_MODE *parent_mode,
int_mv *parent_ref_mv, int mb_row, int mb_col) int_mv *parent_ref_mv, int mb_row, int mb_col)
{ {
LOWER_RES_INFO* store_mode_info LOWER_RES_MB_INFO* store_mode_info
= (LOWER_RES_INFO*)cpi->oxcf.mr_low_res_mode_info; = ((LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info)->mb_info;
unsigned int parent_mb_index; unsigned int parent_mb_index;
//unsigned int parent_mb_index = map_640x480_to_320x240[mb_row][mb_col]; //unsigned int parent_mb_index = map_640x480_to_320x240[mb_row][mb_col];
......
...@@ -549,23 +549,28 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx, ...@@ -549,23 +549,28 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx,
static vpx_codec_err_t vp8e_mr_alloc_mem(const vpx_codec_enc_cfg_t *cfg, static vpx_codec_err_t vp8e_mr_alloc_mem(const vpx_codec_enc_cfg_t *cfg,
void **mem_loc) void **mem_loc)
{ {
vpx_codec_err_t res = 0;
#if CONFIG_MULTI_RES_ENCODING #if CONFIG_MULTI_RES_ENCODING
LOWER_RES_FRAME_INFO *shared_mem_loc;
int mb_rows = ((cfg->g_w + 15) >>4); int mb_rows = ((cfg->g_w + 15) >>4);
int mb_cols = ((cfg->g_h + 15) >>4); int mb_cols = ((cfg->g_h + 15) >>4);
*mem_loc = calloc(mb_rows*mb_cols, sizeof(LOWER_RES_INFO)); shared_mem_loc = calloc(1, sizeof(LOWER_RES_FRAME_INFO));
if(!(*mem_loc)) if(!shared_mem_loc)
{
return VPX_CODEC_MEM_ERROR;
}
shared_mem_loc->mb_info = calloc(mb_rows*mb_cols, sizeof(LOWER_RES_MB_INFO));
if(!(shared_mem_loc->mb_info))
{ {
free(*mem_loc); return VPX_CODEC_MEM_ERROR;
res = VPX_CODEC_MEM_ERROR;
} }
else else
res = VPX_CODEC_OK; {
*mem_loc = (void *)shared_mem_loc;
return VPX_CODEC_OK;
}
#endif #endif
return res;
} }
static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx, static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx,
...@@ -659,7 +664,11 @@ static vpx_codec_err_t vp8e_destroy(vpx_codec_alg_priv_t *ctx) ...@@ -659,7 +664,11 @@ static vpx_codec_err_t vp8e_destroy(vpx_codec_alg_priv_t *ctx)
#if CONFIG_MULTI_RES_ENCODING #if CONFIG_MULTI_RES_ENCODING
/* Free multi-encoder shared memory */ /* Free multi-encoder shared memory */
if (ctx->oxcf.mr_total_resolutions > 0 && (ctx->oxcf.mr_encoder_id == ctx->oxcf.mr_total_resolutions-1)) if (ctx->oxcf.mr_total_resolutions > 0 && (ctx->oxcf.mr_encoder_id == ctx->oxcf.mr_total_resolutions-1))
{
LOWER_RES_FRAME_INFO *shared_mem_loc = (LOWER_RES_FRAME_INFO *)ctx->oxcf.mr_low_res_mode_info;
free(shared_mem_loc->mb_info);
free(ctx->oxcf.mr_low_res_mode_info); free(ctx->oxcf.mr_low_res_mode_info);
}
#endif #endif
free(ctx->cx_data); free(ctx->cx_data);
......
...@@ -288,8 +288,13 @@ int main(int argc, char **argv) ...@@ -288,8 +288,13 @@ int main(int argc, char **argv)
cfg[0].g_lag_in_frames = 0; cfg[0].g_lag_in_frames = 0;
/* Disable automatic keyframe placement */ /* Disable automatic keyframe placement */
/* Note: These 3 settings are copied to all levels. But, except the lowest
* resolution level, all other levels are set to VPX_KF_DISABLED internally.
*/
//cfg[0].kf_mode = VPX_KF_DISABLED; //cfg[0].kf_mode = VPX_KF_DISABLED;
cfg[0].kf_min_dist = cfg[0].kf_max_dist = 1000; cfg[0].kf_mode = VPX_KF_AUTO;
cfg[0].kf_min_dist = 0;
cfg[0].kf_max_dist = 150;
cfg[0].rc_target_bitrate = target_bitrate[0]; /* Set target bitrate */ cfg[0].rc_target_bitrate = target_bitrate[0]; /* Set target bitrate */
cfg[0].g_timebase.num = 1; /* Set fps */ cfg[0].g_timebase.num = 1; /* Set fps */
......
...@@ -117,6 +117,13 @@ vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx, ...@@ -117,6 +117,13 @@ vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx,
mr_cfg.mr_down_sampling_factor.num = dsf->num; mr_cfg.mr_down_sampling_factor.num = dsf->num;
mr_cfg.mr_down_sampling_factor.den = dsf->den; mr_cfg.mr_down_sampling_factor.den = dsf->den;
/* Force Key-frame synchronization. Namely, encoder at higher
* resolution always use the same frame_type chosen by the
* lowest-resolution encoder.
*/
if(mr_cfg.mr_encoder_id)
cfg->kf_mode = VPX_KF_DISABLED;
ctx->iface = iface; ctx->iface = iface;
ctx->name = iface->name; ctx->name = iface->name;
ctx->priv = NULL; ctx->priv = NULL;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment