Merge "Store block-wise statistics obtained in the first pass"
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 3c41f5f..fe15edf 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -599,7 +599,8 @@
#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 @@
// 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 @@
#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 33a795f..e898abc 100644
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -19,6 +19,20 @@
#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;