From 64baa8df2e3f5cd8036fac9715d3f7d348620fa6 Mon Sep 17 00:00:00 2001 From: Scott LaVarnway Date: Thu, 16 Dec 2010 17:01:27 -0500 Subject: [PATCH 1/3] Changed segmentation check order In SPLITMV, the 8x8 segment will be checked first. If the 8x8 rd is better than the best, we check the other segments. Otherwise bail. Adjustments to the thresh_mult were necessary to make up for the initial quality loss. The performance improved by 20% (average) for good quality, speed 0 and speed 1, while the overall quality remained the same. Change-Id: I717aef401323c8a254fba3e9777d2a316c774cc3 --- vp8/encoder/onyx_if.c | 30 ++++++++++++++++++++++++++++-- vp8/encoder/rdopt.c | 31 ++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 3ccffb749..279d50d54 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -683,6 +683,32 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_NEARG ] = 1000; sf->thresh_mult[THR_NEARA ] = 1000; +#if 1 + sf->thresh_mult[THR_ZEROMV ] = 0; + sf->thresh_mult[THR_ZEROG ] = 0; + sf->thresh_mult[THR_ZEROA ] = 0; + sf->thresh_mult[THR_NEARESTMV] = 0; + sf->thresh_mult[THR_NEARESTG ] = 0; + sf->thresh_mult[THR_NEARESTA ] = 0; + sf->thresh_mult[THR_NEARMV ] = 0; + sf->thresh_mult[THR_NEARG ] = 0; + sf->thresh_mult[THR_NEARA ] = 0; + +// sf->thresh_mult[THR_DC ] = 0; + +// sf->thresh_mult[THR_V_PRED ] = 1000; +// sf->thresh_mult[THR_H_PRED ] = 1000; +// sf->thresh_mult[THR_B_PRED ] = 2000; +// sf->thresh_mult[THR_TM ] = 1000; + + sf->thresh_mult[THR_NEWMV ] = 1000; + sf->thresh_mult[THR_NEWG ] = 1000; + sf->thresh_mult[THR_NEWA ] = 1000; + + sf->thresh_mult[THR_SPLITMV ] = 1700; + sf->thresh_mult[THR_SPLITG ] = 4500; + sf->thresh_mult[THR_SPLITA ] = 4500; +#else sf->thresh_mult[THR_NEWMV ] = 1500; sf->thresh_mult[THR_NEWG ] = 1500; sf->thresh_mult[THR_NEWA ] = 1500; @@ -690,7 +716,7 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_SPLITMV ] = 5000; sf->thresh_mult[THR_SPLITG ] = 10000; sf->thresh_mult[THR_SPLITA ] = 10000; - +#endif sf->full_freq[0] = 15; sf->full_freq[1] = 31; @@ -731,7 +757,7 @@ void vp8_set_speed_features(VP8_COMP *cpi) cpi->mode_check_freq[THR_SPLITG] = 4; cpi->mode_check_freq[THR_SPLITA] = 4; - cpi->mode_check_freq[THR_SPLITMV] = 2; + cpi->mode_check_freq[THR_SPLITMV] = 0; sf->thresh_mult[THR_TM ] = 1500; sf->thresh_mult[THR_V_PRED ] = 1500; diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index b541da78e..f1e057918 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -1038,7 +1038,7 @@ typedef struct int d; int segment_yrate; B_PREDICTION_MODE modes[16]; - MV mvs[16]; + int_mv mvs[16]; unsigned char eobs[16]; int mvthresh; @@ -1276,7 +1276,7 @@ void vp8_rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, BEST_SEG_INFO *bsi, { BLOCKD *bd = &x->e_mbd.block[i]; - bsi->mvs[i] = bd->bmi.mv.as_mv; + bsi->mvs[i].as_mv = bd->bmi.mv.as_mv; bsi->modes[i] = bd->bmi.mode; bsi->eobs[i] = bd->eob; } @@ -1305,19 +1305,32 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, { bsi.modes[i] = ZERO4X4; } - - /* original */ - vp8_rd_check_segment(cpi, x, &bsi, 0); - vp8_rd_check_segment(cpi, x, &bsi, 1); - vp8_rd_check_segment(cpi, x, &bsi, 2); - vp8_rd_check_segment(cpi, x, &bsi, 3); + if(cpi->compressor_speed == 0) + { + /* for now, we will keep the original segmentation order + when in best quality mode */ + vp8_rd_check_segment(cpi, x, &bsi, BLOCK_16X8); + vp8_rd_check_segment(cpi, x, &bsi, BLOCK_8X16); + vp8_rd_check_segment(cpi, x, &bsi, BLOCK_8X8); + vp8_rd_check_segment(cpi, x, &bsi, BLOCK_4X4); + } + else + { + vp8_rd_check_segment(cpi, x, &bsi, BLOCK_8X8); + if (bsi.segment_rd < best_rd) + { + vp8_rd_check_segment(cpi, x, &bsi, BLOCK_8X16); + vp8_rd_check_segment(cpi, x, &bsi, BLOCK_16X8); + vp8_rd_check_segment(cpi, x, &bsi, BLOCK_4X4); + } + } /* set it to the best */ for (i = 0; i < 16; i++) { BLOCKD *bd = &x->e_mbd.block[i]; - bd->bmi.mv.as_mv = bsi.mvs[i]; + bd->bmi.mv.as_mv = bsi.mvs[i].as_mv; bd->bmi.mode = bsi.modes[i]; bd->eob = bsi.eobs[i]; } From 2a87491fb07221886c8c570e6b0b48f56855a2c7 Mon Sep 17 00:00:00 2001 From: Henrik Lundin Date: Tue, 14 Dec 2010 14:05:06 +0100 Subject: [PATCH 2/3] Inform caller of decoder about updated references Inform the caller of the decoder if a decoded frame updated last, golden, or altref frames, required for realtime communication proposed in document VP8 RTP payload format. Added a new vpx_codec_control called VP8D_GET_LAST_REF_UPDATES, to be called after vpx_codec_decode. The control will indicate which of the reference frames that were updated by setting the 3 LSBs in the input int (pointer). Change-Id: Iac9db60dac414356c7ffa0b0fede88cb91e11bd7 --- vp8/vp8_dx_iface.c | 21 +++++++++++++++++++++ vpx/vp8dx.h | 24 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index 9dd492217..cf32d1f38 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c @@ -688,6 +688,26 @@ static vpx_codec_err_t vp8_set_dbg_options(vpx_codec_alg_priv_t *ctx, #endif } +static vpx_codec_err_t vp8_get_last_ref_updates(vpx_codec_alg_priv_t *ctx, + int ctrl_id, + va_list args) +{ + int *update_info = va_arg(args, int *); + VP8D_COMP *pbi = (VP8D_COMP *)ctx->pbi; + + if (update_info) + { + *update_info = pbi->common.refresh_alt_ref_frame * (int) VP8_ALTR_FRAME + + pbi->common.refresh_golden_frame * (int) VP8_GOLD_FRAME + + pbi->common.refresh_last_frame * (int) VP8_LAST_FRAME; + + return VPX_CODEC_OK; + } + else + return VPX_CODEC_INVALID_PARAM; +} + + vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = { {VP8_SET_REFERENCE, vp8_set_reference}, @@ -697,6 +717,7 @@ vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = {VP8_SET_DBG_COLOR_MB_MODES, vp8_set_dbg_options}, {VP8_SET_DBG_COLOR_B_MODES, vp8_set_dbg_options}, {VP8_SET_DBG_DISPLAY_MV, vp8_set_dbg_options}, + {VP8D_GET_LAST_REF_UPDATES, vp8_get_last_ref_updates}, { -1, NULL}, }; diff --git a/vpx/vp8dx.h b/vpx/vp8dx.h index fccd407f3..9feab7cc2 100644 --- a/vpx/vp8dx.h +++ b/vpx/vp8dx.h @@ -36,6 +36,30 @@ extern vpx_codec_iface_t* vpx_codec_vp8_dx(void); #include "vp8.h" +/*!\brief VP8 decoder control functions + * + * The set of macros define the control functions of VP8 decoder interface + */ +enum vp8d_dec_control_id +{ + VP8_DECODER_CTRL_ID_START = 256, + VP8D_GET_LAST_REF_UPDATES, /**< control function to get info on which reference frames were updated + by the last decode */ + VP8_DECODER_CTRL_ID_MAX +} ; + + +/*!\brief VP8 encoder control function parameter type + * + * Defines the data types that VP8E control functions take. Note that + * additional common controls are defined in vp8.h + * + */ + + +VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_UPDATES, int *) + + /*! @} - end defgroup vp8_decoder */ From c49f49b113ce06f5dfb67327aab7761f561de0d2 Mon Sep 17 00:00:00 2001 From: John Koleszar Date: Fri, 17 Dec 2010 11:34:02 -0500 Subject: [PATCH 3/3] propagate user private data on decode The pointer passed in the user_priv argument to vpx_codec_decode() should be propagated through to the corresponding output frame and made available in the image's user_priv member. Fixes issue #252 Change-Id: I182746a6882c8549fb146b4a4fdb64f1789eb750 --- vp8/vp8_dx_iface.c | 1 + 1 file changed, 1 insertion(+) diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index cf32d1f38..a2ad59662 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c @@ -466,6 +466,7 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, vpx_img_set_rect(&ctx->img, VP8BORDERINPIXELS, VP8BORDERINPIXELS, sd.y_width, sd.y_height); + ctx->img.user_priv = user_priv; ctx->img_avail = 1; }