multi-res: force Key frame sychronization
authorYunqing Wang <yunqingwang@google.com>
Wed, 16 May 2012 19:06:42 +0000 (15:06 -0400)
committerYunqing Wang <yunqingwang@google.com>
Wed, 16 May 2012 19:06:42 +0000 (15:06 -0400)
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

vp8/common/blockd.h
vp8/encoder/mr_dissim.c
vp8/encoder/onyx_if.c
vp8/encoder/pickinter.c
vp8/vp8_cx_iface.c
vp8_multi_resolution_encoder.c
vpx/src/vpx_encoder.c

index a4c1d92..1945edb 100644 (file)
@@ -168,7 +168,7 @@ typedef struct
 } MODE_INFO;
 
 #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
 {
     MB_PREDICTION_MODE mode;
@@ -176,7 +176,15 @@ typedef struct
     int_mv mv;
     //union b_mode_info bmi[16];
     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
 
 typedef struct blockd
index 7a62a06..564f963 100644 (file)
@@ -65,14 +65,18 @@ void vp8_cal_dissimilarity(VP8_COMP *cpi)
         /* Store info for show/no-show frames for supporting alt_ref.
          * 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)
         {
             int mb_row;
             int mb_col;
             /* Point to beginning of allocated MODE_INFO arrays. */
             MODE_INFO *tmp = cm->mip + cm->mode_info_stride;
-            LOWER_RES_INFO* store_mode_info
-                            = (LOWER_RES_INFO*)cpi->oxcf.mr_low_res_mode_info;
+            LOWER_RES_MB_INFO* store_mode_info = store_info->mb_info;
 
             for (mb_row = 0; mb_row < cm->mb_rows; mb_row ++)
             {
index 8819633..536ae63 100644 (file)
@@ -3241,6 +3241,17 @@ static void encode_frame_to_data_rate
         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
     cpi->mb.e_mbd.update_mb_segmentation_map = 0;
     cpi->mb.e_mbd.update_mb_segmentation_data = 0;
index 618a296..45acb0b 100644 (file)
@@ -405,8 +405,8 @@ void get_lower_res_motion_info(VP8_COMP *cpi, MACROBLOCKD *xd, int *dissim,
                                MB_PREDICTION_MODE *parent_mode,
                                int_mv *parent_ref_mv, int mb_row, int mb_col)
 {
-    LOWER_RES_INFO* store_mode_info
-                          = (LOWER_RES_INFO*)cpi->oxcf.mr_low_res_mode_info;
+    LOWER_RES_MB_INFO* store_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 = map_640x480_to_320x240[mb_row][mb_col];
 
index f55a420..04d4d86 100644 (file)
@@ -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,
                                         void **mem_loc)
 {
-    vpx_codec_err_t res = 0;
-
 #if CONFIG_MULTI_RES_ENCODING
+    LOWER_RES_FRAME_INFO *shared_mem_loc;
     int mb_rows = ((cfg->g_w + 15) >>4);
     int mb_cols = ((cfg->g_h + 15) >>4);
 
-    *mem_loc = calloc(mb_rows*mb_cols, sizeof(LOWER_RES_INFO));
-    if(!(*mem_loc))
+    shared_mem_loc = calloc(1, sizeof(LOWER_RES_FRAME_INFO));
+    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);
-        res = VPX_CODEC_MEM_ERROR;
+        return VPX_CODEC_MEM_ERROR;
     }
     else
-        res = VPX_CODEC_OK;
+    {
+        *mem_loc = (void *)shared_mem_loc;
+        return VPX_CODEC_OK;
+    }
 #endif
-
-    return res;
 }
 
 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)
 #if CONFIG_MULTI_RES_ENCODING
     /* Free multi-encoder shared memory */
     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);
+    }
 #endif
 
     free(ctx->cx_data);
index 78f50c2..81e7137 100644 (file)
@@ -288,8 +288,13 @@ int main(int argc, char **argv)
     cfg[0].g_lag_in_frames   = 0;
 
     /* 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_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].g_timebase.num = 1;                          /* Set fps */
index 03ddc62..db0120c 100644 (file)
@@ -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.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->name = iface->name;
                 ctx->priv = NULL;