summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp8/common/blockd.h3
-rw-r--r--vp8/encoder/mr_dissim.c31
-rw-r--r--vp8/encoder/mr_dissim.h1
-rw-r--r--vp8/encoder/onyx_if.c74
-rw-r--r--vp8/encoder/onyx_int.h4
-rw-r--r--vp8/encoder/pickinter.c32
-rw-r--r--vp8/vp8_cx_iface.c5
-rw-r--r--vp8_multi_resolution_encoder.c13
8 files changed, 142 insertions, 21 deletions
diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h
index c715f6547..acef8caa2 100644
--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -182,6 +182,9 @@ typedef struct
typedef struct
{
FRAME_TYPE frame_type;
+ int is_frame_dropped;
+ /* The frame number of each reference frames */
+ unsigned int low_res_ref_frames[MAX_REF_FRAMES];
LOWER_RES_MB_INFO *mb_info;
} LOWER_RES_FRAME_INFO;
#endif
diff --git a/vp8/encoder/mr_dissim.c b/vp8/encoder/mr_dissim.c
index 564f963f8..71218cca1 100644
--- a/vp8/encoder/mr_dissim.c
+++ b/vp8/encoder/mr_dissim.c
@@ -53,6 +53,7 @@ if(x->mbmi.ref_frame !=INTRA_FRAME) \
void vp8_cal_dissimilarity(VP8_COMP *cpi)
{
VP8_COMMON *cm = &cpi->common;
+ int i;
/* Note: The first row & first column in mip are outside the frame, which
* were initialized to all 0.(ref_frame, mode, mv...)
@@ -72,6 +73,13 @@ void vp8_cal_dissimilarity(VP8_COMP *cpi)
if(cm->frame_type != KEY_FRAME)
{
+ store_info->is_frame_dropped = 0;
+ for (i = 1; i < MAX_REF_FRAMES; i++)
+ store_info->low_res_ref_frames[i] = cpi->current_ref_frames[i];
+ }
+
+ if(cm->frame_type != KEY_FRAME)
+ {
int mb_row;
int mb_col;
/* Point to beginning of allocated MODE_INFO arrays. */
@@ -203,3 +211,26 @@ void vp8_cal_dissimilarity(VP8_COMP *cpi)
}
}
}
+
+/* This function is called only when this frame is dropped at current
+ resolution level. */
+void vp8_store_drop_frame_info(VP8_COMP *cpi)
+{
+ /* If the frame is dropped in lower-resolution encoding, this information
+ is passed to higher resolution level so that the encoder knows there
+ is no mode & motion info available.
+ */
+ if (cpi->oxcf.mr_total_resolutions >1
+ && cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1))
+ {
+ /* 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;
+
+ /* Set frame_type to be INTER_FRAME since we won't drop key frame. */
+ store_info->frame_type = INTER_FRAME;
+ store_info->is_frame_dropped = 1;
+ }
+}
diff --git a/vp8/encoder/mr_dissim.h b/vp8/encoder/mr_dissim.h
index 3d2c2035f..f8cb135d5 100644
--- a/vp8/encoder/mr_dissim.h
+++ b/vp8/encoder/mr_dissim.h
@@ -15,5 +15,6 @@
extern void vp8_cal_low_res_mb_cols(VP8_COMP *cpi);
extern void vp8_cal_dissimilarity(VP8_COMP *cpi);
+extern void vp8_store_drop_frame_info(VP8_COMP *cpi);
#endif
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index d50076d3b..1d8613f38 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -3014,8 +3014,9 @@ static int recode_loop_test( VP8_COMP *cpi,
return force_recode;
}
-static void update_reference_frames(VP8_COMMON *cm)
+static void update_reference_frames(VP8_COMP *cpi)
{
+ VP8_COMMON *cm = &cpi->common;
YV12_BUFFER_CONFIG *yv12_fb = cm->yv12_fb;
/* At this point the new frame has been encoded.
@@ -3030,6 +3031,11 @@ static void update_reference_frames(VP8_COMMON *cm)
yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME;
cm->alt_fb_idx = cm->gld_fb_idx = cm->new_fb_idx;
+
+#if CONFIG_MULTI_RES_ENCODING
+ cpi->current_ref_frames[GOLDEN_FRAME] = cm->current_video_frame;
+ cpi->current_ref_frames[ALTREF_FRAME] = cm->current_video_frame;
+#endif
}
else /* For non key frames */
{
@@ -3040,6 +3046,10 @@ static void update_reference_frames(VP8_COMMON *cm)
cm->yv12_fb[cm->new_fb_idx].flags |= VP8_ALTR_FRAME;
cm->yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME;
cm->alt_fb_idx = cm->new_fb_idx;
+
+#if CONFIG_MULTI_RES_ENCODING
+ cpi->current_ref_frames[ALTREF_FRAME] = cm->current_video_frame;
+#endif
}
else if (cm->copy_buffer_to_arf)
{
@@ -3052,6 +3062,11 @@ static void update_reference_frames(VP8_COMMON *cm)
yv12_fb[cm->lst_fb_idx].flags |= VP8_ALTR_FRAME;
yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME;
cm->alt_fb_idx = cm->lst_fb_idx;
+
+#if CONFIG_MULTI_RES_ENCODING
+ cpi->current_ref_frames[ALTREF_FRAME] =
+ cpi->current_ref_frames[LAST_FRAME];
+#endif
}
}
else /* if (cm->copy_buffer_to_arf == 2) */
@@ -3061,6 +3076,11 @@ static void update_reference_frames(VP8_COMMON *cm)
yv12_fb[cm->gld_fb_idx].flags |= VP8_ALTR_FRAME;
yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME;
cm->alt_fb_idx = cm->gld_fb_idx;
+
+#if CONFIG_MULTI_RES_ENCODING
+ cpi->current_ref_frames[ALTREF_FRAME] =
+ cpi->current_ref_frames[GOLDEN_FRAME];
+#endif
}
}
}
@@ -3072,6 +3092,10 @@ static void update_reference_frames(VP8_COMMON *cm)
cm->yv12_fb[cm->new_fb_idx].flags |= VP8_GOLD_FRAME;
cm->yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FRAME;
cm->gld_fb_idx = cm->new_fb_idx;
+
+#if CONFIG_MULTI_RES_ENCODING
+ cpi->current_ref_frames[GOLDEN_FRAME] = cm->current_video_frame;
+#endif
}
else if (cm->copy_buffer_to_gf)
{
@@ -3084,6 +3108,11 @@ static void update_reference_frames(VP8_COMMON *cm)
yv12_fb[cm->lst_fb_idx].flags |= VP8_GOLD_FRAME;
yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FRAME;
cm->gld_fb_idx = cm->lst_fb_idx;
+
+#if CONFIG_MULTI_RES_ENCODING
+ cpi->current_ref_frames[GOLDEN_FRAME] =
+ cpi->current_ref_frames[LAST_FRAME];
+#endif
}
}
else /* if (cm->copy_buffer_to_gf == 2) */
@@ -3093,6 +3122,11 @@ static void update_reference_frames(VP8_COMMON *cm)
yv12_fb[cm->alt_fb_idx].flags |= VP8_GOLD_FRAME;
yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FRAME;
cm->gld_fb_idx = cm->alt_fb_idx;
+
+#if CONFIG_MULTI_RES_ENCODING
+ cpi->current_ref_frames[GOLDEN_FRAME] =
+ cpi->current_ref_frames[ALTREF_FRAME];
+#endif
}
}
}
@@ -3103,6 +3137,10 @@ static void update_reference_frames(VP8_COMMON *cm)
cm->yv12_fb[cm->new_fb_idx].flags |= VP8_LAST_FRAME;
cm->yv12_fb[cm->lst_fb_idx].flags &= ~VP8_LAST_FRAME;
cm->lst_fb_idx = cm->new_fb_idx;
+
+#if CONFIG_MULTI_RES_ENCODING
+ cpi->current_ref_frames[LAST_FRAME] = cm->current_video_frame;
+#endif
}
}
@@ -3313,8 +3351,28 @@ static void encode_frame_to_data_rate
*/
if (cpi->oxcf.mr_encoder_id)
{
- cm->frame_type =
- ((LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info)->frame_type;
+ LOWER_RES_FRAME_INFO* low_res_frame_info
+ = (LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info;
+
+ cm->frame_type = low_res_frame_info->frame_type;
+
+ if(cm->frame_type != KEY_FRAME)
+ {
+ cpi->mr_low_res_mv_avail = 1;
+ cpi->mr_low_res_mv_avail &= !(low_res_frame_info->is_frame_dropped);
+
+ if (cpi->ref_frame_flags & VP8_LAST_FRAME)
+ cpi->mr_low_res_mv_avail &= (cpi->current_ref_frames[LAST_FRAME]
+ == low_res_frame_info->low_res_ref_frames[LAST_FRAME]);
+
+ if (cpi->ref_frame_flags & VP8_GOLD_FRAME)
+ cpi->mr_low_res_mv_avail &= (cpi->current_ref_frames[GOLDEN_FRAME]
+ == low_res_frame_info->low_res_ref_frames[GOLDEN_FRAME]);
+
+ if (cpi->ref_frame_flags & VP8_ALTR_FRAME)
+ cpi->mr_low_res_mv_avail &= (cpi->current_ref_frames[ALTREF_FRAME]
+ == low_res_frame_info->low_res_ref_frames[ALTREF_FRAME]);
+ }
}
#endif
@@ -3422,6 +3480,10 @@ static void encode_frame_to_data_rate
if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size)
cpi->bits_off_target = cpi->oxcf.maximum_buffer_size;
+#if CONFIG_MULTI_RES_ENCODING
+ vp8_store_drop_frame_info(cpi);
+#endif
+
cm->current_video_frame++;
cpi->frames_since_key++;
@@ -3459,6 +3521,10 @@ static void encode_frame_to_data_rate
/* Decide how big to make the frame */
if (!vp8_pick_frame_size(cpi))
{
+ /*TODO: 2 drop_frame and return code could be put together. */
+#if CONFIG_MULTI_RES_ENCODING
+ vp8_store_drop_frame_info(cpi);
+#endif
cm->current_video_frame++;
cpi->frames_since_key++;
return;
@@ -4231,7 +4297,7 @@ static void encode_frame_to_data_rate
vp8_loopfilter_frame(cpi, cm);
}
- update_reference_frames(cm);
+ update_reference_frames(cpi);
#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
if (cpi->oxcf.error_resilient_mode)
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index 808080f22..584cadae6 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -701,6 +701,10 @@ typedef struct VP8_COMP
#if CONFIG_MULTI_RES_ENCODING
/* Number of MBs per row at lower-resolution level */
int mr_low_res_mb_cols;
+ /* Indicate if lower-res mv info is available */
+ unsigned char mr_low_res_mv_avail;
+ /* The frame number of each reference frames */
+ unsigned int current_ref_frames[MAX_REF_FRAMES];
#endif
struct rd_costs_struct
diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c
index e2e052f2e..75e262eab 100644
--- a/vp8/encoder/pickinter.c
+++ b/vp8/encoder/pickinter.c
@@ -542,7 +542,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int_mv parent_ref_mv;
MB_PREDICTION_MODE parent_mode = 0;
- if (cpi->oxcf.mr_encoder_id)
+ if (cpi->oxcf.mr_encoder_id && cpi->mr_low_res_mv_avail)
get_lower_res_motion_info(cpi, xd, &dissim, &parent_ref_frame,
&parent_mode, &parent_ref_mv, mb_row, mb_col);
#endif
@@ -600,11 +600,14 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame;
#if CONFIG_MULTI_RES_ENCODING
- if (cpi->oxcf.mr_encoder_id)
+ if (cpi->oxcf.mr_encoder_id && cpi->mr_low_res_mv_avail)
{
- /* If parent MB is intra, child MB is intra. */
- if (!parent_ref_frame && this_ref_frame)
- continue;
+ /* TODO: If parent MB is intra, child MB is intra. This is removed
+ * now since it cause noticeable quality loss for some test clip.
+ * Will come back to evaluate more.
+ * if (!parent_ref_frame && this_ref_frame)
+ * continue;
+ */
/* If parent MB is inter, and it is unlikely there are multiple
* objects in parent MB, we use parent ref frame as child MB's
@@ -630,7 +633,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
}
#if CONFIG_MULTI_RES_ENCODING
- if (cpi->oxcf.mr_encoder_id)
+ if (cpi->oxcf.mr_encoder_id && cpi->mr_low_res_mv_avail)
{
if (vp8_mode_order[mode_index] == NEARESTMV &&
mode_mv[NEARESTMV].as_int ==0)
@@ -783,7 +786,14 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
step_param = cpi->sf.first_step + speed_adjust;
#if CONFIG_MULTI_RES_ENCODING
- if (cpi->oxcf.mr_encoder_id)
+ /* If lower-res drops this frame, then higher-res encoder does
+ motion search without any previous knowledge. Also, since
+ last frame motion info is not stored, then we can not
+ use improved_mv_pred. */
+ if (cpi->oxcf.mr_encoder_id && !cpi->mr_low_res_mv_avail)
+ cpi->sf.improved_mv_pred = 0;
+
+ if (cpi->oxcf.mr_encoder_id && cpi->mr_low_res_mv_avail)
{
/* Use parent MV as predictor. Adjust search range
* accordingly.
@@ -827,7 +837,8 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
}
#if CONFIG_MULTI_RES_ENCODING
- if (cpi->oxcf.mr_encoder_id && dissim <= 2 &&
+ if (cpi->oxcf.mr_encoder_id && cpi->mr_low_res_mv_avail &&
+ dissim <= 2 &&
MAX(abs(best_ref_mv.as_mv.row - parent_ref_mv.as_mv.row),
abs(best_ref_mv.as_mv.col - parent_ref_mv.as_mv.col)) <= 4)
{
@@ -864,7 +875,10 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
* change the behavior in lowest-resolution encoder.
* Will improve it later.
*/
- if (!cpi->oxcf.mr_encoder_id)
+ /* Set step_param to 0 to ensure large-range motion search
+ when encoder drops this frame at lower-resolution.
+ */
+ if (!cpi->oxcf.mr_encoder_id || !cpi->mr_low_res_mv_avail)
step_param = 0;
#endif
bestsme = vp8_hex_search(x, b, d, &mvp_full, &d->bmi.mv,
diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c
index 3a87ad830..072314f24 100644
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -163,14 +163,11 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
* multi-res-encoder.*/
#if CONFIG_MULTI_RES_ENCODING
if (ctx->base.enc.total_encoders > 1)
- {
RANGE_CHECK_HI(cfg, rc_resize_allowed, 0);
- RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 0);
- }
#else
RANGE_CHECK_BOOL(cfg, rc_resize_allowed);
- RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100);
#endif
+ RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100);
RANGE_CHECK_HI(cfg, rc_resize_up_thresh, 100);
RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100);
diff --git a/vp8_multi_resolution_encoder.c b/vp8_multi_resolution_encoder.c
index 497d8f7e1..eae36a4da 100644
--- a/vp8_multi_resolution_encoder.c
+++ b/vp8_multi_resolution_encoder.c
@@ -273,7 +273,7 @@ int main(int argc, char **argv)
cfg[0].g_w = width;
cfg[0].g_h = height;
cfg[0].g_threads = 1; /* number of threads used */
- cfg[0].rc_dropframe_thresh = 0;
+ cfg[0].rc_dropframe_thresh = 30;
cfg[0].rc_end_usage = VPX_CBR;
cfg[0].rc_resize_allowed = 0;
cfg[0].rc_min_quantizer = 4;
@@ -283,7 +283,6 @@ int main(int argc, char **argv)
cfg[0].rc_buf_initial_sz = 500;
cfg[0].rc_buf_optimal_sz = 600;
cfg[0].rc_buf_sz = 1000;
- //cfg[0].rc_dropframe_thresh = 10;
cfg[0].g_error_resilient = 1; /* Enable error resilient mode */
cfg[0].g_lag_in_frames = 0;
@@ -293,8 +292,8 @@ int main(int argc, char **argv)
*/
//cfg[0].kf_mode = VPX_KF_DISABLED;
cfg[0].kf_mode = VPX_KF_AUTO;
- cfg[0].kf_min_dist = 0;
- cfg[0].kf_max_dist = 150;
+ cfg[0].kf_min_dist = 3000;
+ cfg[0].kf_max_dist = 3000;
cfg[0].rc_target_bitrate = target_bitrate[0]; /* Set target bitrate */
cfg[0].g_timebase.num = 1; /* Set fps */
@@ -366,6 +365,12 @@ int main(int argc, char **argv)
if(vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, static_thresh))
die_codec(&codec[i], "Failed to set static threshold");
}
+ /* Set NOISE_SENSITIVITY to do TEMPORAL_DENOISING */
+ for ( i=0; i< NUM_ENCODERS; i++)
+ {
+ if(vpx_codec_control(&codec[i], VP8E_SET_NOISE_SENSITIVITY, 0))
+ die_codec(&codec[i], "Failed to set noise_sensitivity");
+ }
frame_avail = 1;
got_data = 0;