From bae652245d46e1b500e5c2ca5c2fd451dab291da Mon Sep 17 00:00:00 2001 From: Pengchong Jin <pengchong@google.com> Date: Fri, 25 Jul 2014 11:07:44 -0700 Subject: [PATCH] Store block-wise statistics obtained in the first pass Change-Id: I9956db2ba2f7d28f484daaf5022d8d1ef5db473c --- vp9/encoder/vp9_firstpass.c | 60 +++++++++++++++++++++++++++++++++++-- vp9/encoder/vp9_firstpass.h | 14 +++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 3c41f5f735..fe15edfdc5 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -599,7 +599,8 @@ void vp9_first_pass(VP9_COMP *cpi) { #if CONFIG_FP_MB_STATS if (cpi->use_fp_mb_stats) { - // TODO(pengchong): store some related block statistics here + // initialization + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] = 0; } #endif @@ -700,6 +701,33 @@ void vp9_first_pass(VP9_COMP *cpi) { // Start by assuming that intra mode is best. best_ref_mv.as_int = 0; +#if CONFIG_FP_MB_STATS + if (cpi->use_fp_mb_stats) { + // intra predication statistics + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] = 0; + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_DCINTRA_MASK; + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] &= + (~FPMB_NONZERO_MOTION_MASK); + if (this_error > FPMB_ERROR_LEVEL4_TH) { + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_ERROR_LEVEL4_MASK; + } else if (this_error > FPMB_ERROR_LEVEL3_TH) { + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_ERROR_LEVEL3_MASK; + } else if (this_error > FPMB_ERROR_LEVEL2_TH) { + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_ERROR_LEVEL2_MASK; + } else if (this_error > FPMB_ERROR_LEVEL1_TH) { + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_ERROR_LEVEL1_MASK; + } else { + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_ERROR_LEVEL0_MASK; + } + } +#endif + if (motion_error <= this_error) { // Keep a count of cases where the inter and intra were very close // and very low. This helps with scene cut detection for example in @@ -730,13 +758,41 @@ void vp9_first_pass(VP9_COMP *cpi) { #if CONFIG_FP_MB_STATS if (cpi->use_fp_mb_stats) { - // TODO(pengchong): save some related block statistics here + // inter predication statistics + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] = 0; + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] &= + (~FPMB_DCINTRA_MASK); + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] &= + (~FPMB_NONZERO_MOTION_MASK); + if (this_error > FPMB_ERROR_LEVEL4_TH) { + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_ERROR_LEVEL4_MASK; + } else if (this_error > FPMB_ERROR_LEVEL3_TH) { + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_ERROR_LEVEL3_MASK; + } else if (this_error > FPMB_ERROR_LEVEL2_TH) { + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_ERROR_LEVEL2_MASK; + } else if (this_error > FPMB_ERROR_LEVEL1_TH) { + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_ERROR_LEVEL1_MASK; + } else { + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_ERROR_LEVEL0_MASK; + } } #endif if (mv.as_int) { ++mvcount; +#if CONFIG_FP_MB_STATS + if (cpi->use_fp_mb_stats) { + cpi->twopass.frame_mb_stats_buf[mb_row * cm->mb_cols + mb_col] |= + FPMB_NONZERO_MOTION_MASK; + } +#endif + // Non-zero vector, was it different from the last non zero vector? if (mv.as_int != lastmv_as_int) ++new_mv_count; diff --git a/vp9/encoder/vp9_firstpass.h b/vp9/encoder/vp9_firstpass.h index 33a795f265..e898abc161 100644 --- a/vp9/encoder/vp9_firstpass.h +++ b/vp9/encoder/vp9_firstpass.h @@ -19,6 +19,20 @@ extern "C" { #endif #if CONFIG_FP_MB_STATS + +#define FPMB_DCINTRA_MASK 0x01 +#define FPMB_NONZERO_MOTION_MASK 0x02 +#define FPMB_ERROR_LEVEL0_MASK 0x04 +#define FPMB_ERROR_LEVEL1_MASK 0x10 +#define FPMB_ERROR_LEVEL2_MASK 0x20 +#define FPMB_ERROR_LEVEL3_MASK 0x40 +#define FPMB_ERROR_LEVEL4_MASK 0x80 + +#define FPMB_ERROR_LEVEL1_TH 2000 +#define FPMB_ERROR_LEVEL2_TH 8000 +#define FPMB_ERROR_LEVEL3_TH 24000 +#define FPMB_ERROR_LEVEL4_TH 48000 + typedef struct { uint8_t *mb_stats_start; uint8_t *mb_stats_end; -- GitLab